Statistics
| Revision:

root / org.gvsig.dgn / trunk / org.gvsig.dgn / org.gvsig.dgn.provider / src / main / java / org / gvsig / fmap / dal / store / dgn / DGNStoreProvider.java @ 6

History | View | Annotate | Download (30.2 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.FileHelper;
19
import org.gvsig.fmap.dal.exception.DataException;
20
import org.gvsig.fmap.dal.exception.InitializeException;
21
import org.gvsig.fmap.dal.exception.OpenException;
22
import org.gvsig.fmap.dal.exception.ReadException;
23
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
24
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
25
import org.gvsig.fmap.dal.feature.EditableFeatureType;
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.ResourceAction;
32
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
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.DGNElemComplexHeader;
41
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCore;
42
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemMultiPoint;
43
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemText;
44
import org.gvsig.fmap.dal.store.dgn.lib.DGNFileHeader;
45
import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.fmap.geom.GeometryLocator;
48
import org.gvsig.fmap.geom.GeometryManager;
49
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
50
import org.gvsig.fmap.geom.Geometry.TYPES;
51
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
52
import org.gvsig.fmap.geom.exception.CreateGeometryException;
53
import org.gvsig.fmap.geom.primitive.Envelope;
54
import org.gvsig.fmap.geom.primitive.GeneralPathX;
55
import org.gvsig.fmap.geom.primitive.Point;
56
import org.gvsig.tools.dynobject.exception.DynMethodException;
57

    
58
public class DGNStoreProvider extends AbstractMemoryStoreProvider implements
59
                ResourceConsumer {
60
//        private static final Logger logger = LoggerFactory.getLogger(DGNStoreProvider.class);
61

    
62
        public static final String NAME = "DGN";
63
        public static final String DESCRIPTION = "DGN file";
64
        
65
        public static final String METADATA_DEFINITION_NAME = NAME;
66
        private static final String METADATA_DEFINITION_DESCRIPTION = "DGN File Store";
67

    
68
        private static final String NAME_FIELD_ID = "ID";
69
        private static final String NAME_FIELD_GEOMETRY = "Geometry";
70
        private static final String NAME_FIELD_ENTITY = "Entity";
71
        private static final String NAME_FIELD_LAYER = "Layer";
72
        public static final String NAME_FIELD_COLOR = "Color";
73
//        private static final String NAME_FIELD_ELEVATION = "Elevation";
74
//        private static final String NAME_FIELD_THICKNESS = "Thickness";
75
        public static final String NAME_FIELD_TEXT = "Text";
76
        public static final String NAME_FIELD_HEIGHTTEXT = "HeightText";
77
        public static final String NAME_FIELD_ROTATIONTEXT = "Rotation";
78

    
79

    
80
        private int ID_FIELD_ID = 0;
81
        private int ID_FIELD_ENTITY = 1;
82
        private int ID_FIELD_LAYER = 2;
83
        private int ID_FIELD_COLOR = 3;
84
//        private int ID_FIELD_ELEVATION = 4;
85
//        private int ID_FIELD_THICKNESS = 5;
86
        private int ID_FIELD_TEXT = 6;
87
        private int ID_FIELD_HEIGHTTEXT = 7;
88
        private int ID_FIELD_ROTATIONTEXT = 8;
89
//        private int ID_FIELD_GEOMETRY = 9;
90

    
91
        private IProjection projection;
92
        private ResourceProvider resource;
93
        private LegendBuilder legendBuilder;
94

    
95
        private long counterNewsOIDs = 0;
96
        protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
97

    
98
        public DGNStoreProvider(DGNStoreParameters parameters,
99
                        DataStoreProviderServices storeServices) throws InitializeException {
100
                super(
101
                        parameters, 
102
                        storeServices, 
103
                        FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
104
                );
105

    
106
                counterNewsOIDs = 0;
107
                //                projection = CRSFactory.getCRS(getParameters().getSRSID());
108

    
109
                File file = getDGNParameters().getFile();
110
                resource = this.createResource(
111
                                FileResource.NAME,
112
                                new Object[] { file.getAbsolutePath() }
113
                        );
114

    
115
                resource.addConsumer(this);
116

    
117
                this.projection = this.getDGNParameters().getCRS();
118

    
119

    
120
                try {
121
                        legendBuilder = (LegendBuilder) this.invokeDynMethod(
122
                                        LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
123
                } catch (DynMethodException e) {
124
                        legendBuilder = null;
125
                } catch (Exception e) {
126
                        throw new InitializeException(e);
127
                }
128

    
129
                this.initializeFeatureTypes();
130

    
131
        }
132

    
133
        private DGNStoreParameters getDGNParameters() {
134
                return (DGNStoreParameters) this.getParameters();
135
        }
136

    
137

    
138
        public String getProviderName() {
139
                return NAME;
140
        }
141

    
142
        public boolean allowWrite() {
143
            // not yet
144
                return false;
145
        }
146

    
147
        public Object getLegend() throws OpenException {
148
                this.open();
149
                if (legendBuilder == null) {
150
                        return null;
151
                }
152
                return legendBuilder.getLegend();
153
        }
154

    
155
        public Object getLabeling() throws OpenException {
156
                this.open();
157
                if (legendBuilder == null) {
158
                        return null;
159
                }
160
                return legendBuilder.getLabeling();
161
        }
162

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

    
180
                        }
181
                        newEnvelope.setLowerCorner(envelope.getLowerCorner());
182
                        newEnvelope.setUpperCorner(envelope.getUpperCorner());
183
                        return newEnvelope;
184
                }
185
        }
186

    
187
        public void open() throws OpenException {
188
                if (this.data != null) {
189
                        return;
190
                }
191
                try {
192
                        getResource().execute(new ResourceAction() {
193
                                public Object run() throws Exception {
194
                                        FeatureStoreProviderServices store = getStoreServices();
195
                                        DGNData DGNData = null;
196
                                        if (resource.getData() != null) {
197
                                                DGNData =
198
                                                                (DGNData) ((Map) resource.getData()).get(projection.getAbrev()); // OJO
199
                                                // no es del todo correcto (puede llevar reproyeccion)
200
                                        } else {
201
                                                resource.setData(new HashMap());
202
                                        }
203
                                        if (DGNData == null) {
204
                                                DGNData = new DGNData();
205
                                                DGNData.data = new ArrayList();
206
                                                data = DGNData.data;
207
                                                counterNewsOIDs = 0;
208
                                                Reader reader =
209
                                                                new Reader().initialice(getMemoryProvider(),
210
                                                                                (File)resource.get(),
211
                                                                                projection, legendBuilder);
212
                                                reader.begin(store);
213
                                                DGNData.defaultFType =
214
                                                                reader.getDefaultType().getNotEditableCopy();
215
                                                List types = new ArrayList();
216
                                                Iterator it = reader.getTypes().iterator();
217
                                                EditableFeatureType fType;
218
                                                while (it.hasNext()) {
219
                                                        fType = (EditableFeatureType) it.next();
220
                                                        if (fType.getId().equals(
221
                                                                        DGNData.defaultFType.getId())) {
222
                                                                types.add(DGNData.defaultFType);
223
                                                        } else {
224
                                                                types.add(fType.getNotEditableCopy());
225
                                                        }
226
                                                }
227
                                                DGNData.fTypes = types;
228

    
229
                                                resource.notifyOpen();
230
                                                store.setFeatureTypes(DGNData.fTypes,
231
                                                                DGNData.defaultFType);
232
                                                reader.load();
233
                                                // envelope = reader.getEnvelope();
234

    
235
                                                DGNData.envelope = reader.getEnvelope();
236

    
237
                                                DGNData.legendBuilder = legendBuilder;
238

    
239
                                                DGNData.projection = projection;
240

    
241
                                                reader.end();
242
                                                resource.notifyClose();
243
                                                ((Map) resource.getData()).put(projection.getAbrev(),
244
                                                                DGNData); // OJO la
245
                                                // reproyeccion
246
                                        }
247

    
248
                                        data = DGNData.data;
249
                                        store.setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
250
                                        legendBuilder = DGNData.legendBuilder;
251
                                        setDynValue("Envelope", DGNData.getEnvelopeCopy());
252
                                        setDynValue("CRS", projection);
253
                                        counterNewsOIDs = data.size();
254
                                        return null;
255
                                }
256
                        });
257
                } catch (Exception e) {
258
                        data = null;
259
                        try {
260
                                throw new OpenException(resource.getName(), e);
261
                        } catch (AccessResourceException e1) {
262
                                throw new OpenException(getProviderName(), e);
263
                        }
264
                }
265
        }
266

    
267

    
268
        public DataServerExplorer getExplorer() throws ReadException {
269
                DataManager manager = DALLocator.getDataManager();
270
                FilesystemServerExplorerParameters params;
271
                try {
272
                        params = (FilesystemServerExplorerParameters) manager
273
                                .createServerExplorerParameters(FilesystemServerExplorer.NAME);
274
                        params.setRoot(this.getDGNParameters().getFile().getParent());
275
                        return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
276
                } catch (DataException e) {
277
                        throw new ReadException(this.getProviderName(), e);
278
                } catch (ValidateDataParametersException e) {
279
                        throw new ReadException(this.getProviderName(), e);
280
                }
281

    
282
        }
283

    
284

    
285

    
286
        public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
287
                // FIXME Exception
288
                throw new UnsupportedOperationException();
289
        }
290

    
291
        public class Reader {
292
                private File file;
293
//                private String fileName;
294
                private IProjection projection;
295
                private List types;
296
                private LegendBuilder leyendBuilder;
297
                private AbstractMemoryStoreProvider store;
298
                private Envelope envelope;
299

    
300
                public Reader initialice(AbstractMemoryStoreProvider store, File file,
301
                                IProjection projection,
302
                                LegendBuilder leyendBuilder) {
303
                        this.store = store;
304
                        this.file = file;
305
//                        this.fileName = file.getAbsolutePath();
306
                        this.projection = projection;
307
                        this.leyendBuilder = leyendBuilder;
308
                        if (leyendBuilder != null) {
309
                                leyendBuilder.initialize(store);
310
                        }
311
                        return this;
312
                }
313

    
314
                public Envelope getEnvelope() {
315
                        return this.envelope;
316
                }
317

    
318
                public void begin(FeatureStoreProviderServices store) {
319

    
320
                        EditableFeatureType featureType = store.createFeatureType();
321

    
322
                        featureType.setHasOID(true);
323

    
324
                        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
325
                                        .setDefaultValue(Integer.valueOf(0))
326
                                .getIndex();
327

    
328
                        // FIXME: Cual es el size y el valor por defecto para Entity ?
329
                        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY,
330
                                        DataTypes.STRING, 100)
331
                                        .setDefaultValue("")
332
                                        .getIndex();
333

    
334
                        // FIXME: Cual es el size de Layer ?
335
                        ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER,
336
                                        DataTypes.STRING, 100)
337
                                        .setDefaultValue(
338
                                        "default").getIndex();
339

    
340
                        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR,
341
                                        DataTypes.INT)
342
                                        .setDefaultValue(
343
                                        Integer.valueOf(0)).getIndex();
344

    
345
//                        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION,
346
//                                        DataTypes.DOUBLE)
347
//                                        .setDefaultValue(
348
//                                        Double.valueOf(0)).getIndex();
349
//
350
//                        ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS,
351
//                                        DataTypes.DOUBLE)
352
//                                        .setDefaultValue(
353
//                                        Double.valueOf(0)).getIndex();
354
//
355
                        // FIXME: Cual es el size de Text ?
356
                        ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT,
357
                                        DataTypes.STRING, 100)
358
                                        .setDefaultValue("")
359
                                        .getIndex();
360

    
361
                        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT,
362
                                        DataTypes.DOUBLE).setDefaultValue(
363
                                        Double.valueOf(10)).getIndex();
364

    
365
                        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT,
366
                                        DataTypes.DOUBLE).setDefaultValue(
367
                                        Double.valueOf(0)).getIndex();
368

    
369

    
370
                        EditableFeatureAttributeDescriptor attr = featureType.add(
371
                                        NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
372
                        attr.setSRS(this.projection);
373
                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
374
                        attr.setGeometrySubType(Geometry.SUBTYPES.GEOM3D);
375
//                        ID_FIELD_GEOMETRY = attr.getIndex();
376

    
377
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
378

    
379

    
380
                        // FIXME: Parece que el DGN puede tener mas atributos opcionales.
381
                        // Habria que ver de pillarlos ?
382

    
383
                        types = new ArrayList();
384
                        types.add(featureType);
385

    
386
                        if (leyendBuilder != null) {
387
                                leyendBuilder.begin();
388
                        }
389

    
390
                }
391

    
392
                public void end() {
393
                        if (leyendBuilder != null) {
394
                                leyendBuilder.end();
395
                        }
396
                }
397

    
398
                public List getTypes() {
399
                        return types;
400
                }
401

    
402
                public EditableFeatureType getDefaultType() {
403
                        return (EditableFeatureType) types.get(0);
404
                }
405

    
406
//                private Double toDouble(String value) {
407
//                        if (value == null) {
408
//                                return Double.valueOf(0);
409
//                        }
410
//                        return Double.valueOf(value);
411
//                }
412

    
413
                public void load() throws DataException {
414

    
415
                        this.envelope = null;
416

    
417
                        DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
418

    
419
                        FeatureType type = getDefaultType().getNotEditableCopy();
420
                        int fTypeSize = type.size();
421
                        Object[] auxRow = new Object[fTypeSize];
422
                        Object[] cellRow = new Object[fTypeSize];
423
                        Object[] complexRow = new Object[fTypeSize];
424

    
425
                        boolean bElementoCompuesto = false;
426
                        boolean bEsPoligono = false;
427
                        boolean bInsideCell = false;
428
                        boolean bFirstHoleEntity = false;
429
                        boolean bConnect = false; // Se usa para que los pol?gonos cierren
430
                                                                                // bien cuando son formas compuestas
431
//                        int contadorSubElementos = 0;
432
//                        int numSubElementos = 0;
433
                        int complex_index_fill_color = -1;
434
                        int nClass; // Para filtrar los elementos de construcci?n, etc.
435
                        GeneralPathX elementoCompuesto = new GeneralPathX(
436
                                        GeneralPathX.WIND_EVEN_ODD);
437

    
438
                        for (int id = 0; id < dgnReader.getNumEntities(); id++) {
439
                                // System.out.println("Elemento " + id + " de " +
440
                                // dgnReader.getNumEntities());
441
                                dgnReader.DGNGotoElement(id);
442

    
443
                                DGNElemCore elemento = dgnReader.DGNReadElement();
444
                                nClass = 0;
445
                                auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0);
446
                                auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0);
447
                                auxRow[ID_FIELD_TEXT] = null;
448

    
449
                                if (elemento.properties != 0) {
450
                                        nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS;
451
                                }
452

    
453
                                if ((elemento != null) && (elemento.deleted == 0)
454
                                                && (nClass == 0)) // Leer un elemento
455
                                {
456

    
457
                                        // if ((elemento.element_id > 3800) && (elemento.element_id
458
                                        // < 3850))
459
                                        // dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
460
                                        if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
461
                                                        || (elemento.stype == DGNFileHeader.DGNST_ARC)
462
                                                        || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER)
463
                                                        || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN)
464
                                                        || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) {
465
                                                if (elemento.complex != 0) {
466
                                                        bElementoCompuesto = true;
467
                                                } else {
468
                                                        if (bElementoCompuesto) {
469
                                                                if (bInsideCell) {
470
                                                                        auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY];
471
                                                                } else {
472
                                                                        auxRow = complexRow;
473
                                                                }
474

    
475
                                                                // System.err.println("Entidad compuesta. bInsideCell = "
476
                                                                // + bInsideCell + " auxRow = " +
477
                                                                // auxRow[ID_FIELD_ENTITY]);
478
                                                                // addShape(new FPolyline2D(elementoCompuesto),
479
                                                                // auxRow);
480
                                                                addShape(createMultiCurve(elementoCompuesto),
481
                                                                                auxRow, type, dgnReader);
482

    
483
                                                                if (bEsPoligono) {
484
                                                                        if (complex_index_fill_color != -1) {
485
                                                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
486
                                                                        }
487

    
488
                                                                        addShape(
489
                                                                                        createMultiSurface(elementoCompuesto),
490
                                                                                        auxRow, type, dgnReader);
491
                                                                }
492

    
493
                                                                elementoCompuesto = new GeneralPathX(
494
                                                                                GeneralPathX.WIND_EVEN_ODD);
495
                                                        }
496

    
497
                                                        // System.err.println("Entidad simple");
498
                                                        bElementoCompuesto = false;
499
                                                        bEsPoligono = false;
500
                                                        bConnect = false;
501

    
502
                                                        // elementoCompuesto = new GeneralPathX();
503
                                                        bInsideCell = false;
504
                                                }
505
                                        }
506

    
507
                                        switch (elemento.stype) {
508
                                        case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
509
                                                bInsideCell = true;
510
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
511
                                                cellRow[ID_FIELD_LAYER] = String
512
                                                                .valueOf(elemento.level);
513
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
514
                                                cellRow[ID_FIELD_ENTITY] = "Shared Cell";
515

    
516
                                                break;
517

    
518
                                        case DGNFileHeader.DGNST_CELL_HEADER:
519
                                                bInsideCell = true;
520

    
521
//                                                DGNElemCellHeader psCellHeader = (DGNElemCellHeader) elemento;
522
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
523
                                                cellRow[ID_FIELD_LAYER] = String
524
                                                                .valueOf(elemento.level);
525
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
526
                                                cellRow[ID_FIELD_ENTITY] = "Cell";
527
                                                complex_index_fill_color = dgnReader
528
                                                                .DGNGetShapeFillInfo(elemento);
529

    
530
                                                // System.err.println("Cell Header " +
531
                                                // complex_index_fill_color);
532
                                                break;
533

    
534
                                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
535

    
536
                                                // bElementoCompuesto = true;
537
                                                // System.err.println("Complex Header");
538
//                                                contadorSubElementos = 0;
539

    
540
                                                DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento;
541
//                                                numSubElementos = psComplexHeader.numelems;
542
                                                complexRow[ID_FIELD_ID] = elemento.element_id;
543
                                                complexRow[ID_FIELD_LAYER] = String
544
                                                                .valueOf(elemento.level);
545
                                                complexRow[ID_FIELD_COLOR] = elemento.color;
546
                                                complexRow[ID_FIELD_ENTITY] = "Complex";
547

    
548
                                                if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
549
                                                        bEsPoligono = true;
550

    
551
                                                        // Si es un agujero, no conectamos con el anterior
552
                                                        if ((psComplexHeader.properties & 0x8000) != 0) {
553
                                                                bFirstHoleEntity = true;
554
                                                        } else {
555
                                                                // Miramos si tiene color de relleno
556
                                                                // complex_index_fill_color = -1;
557
                                                                // if (elemento.attr_bytes > 0) {
558
                                                                complex_index_fill_color = dgnReader
559
                                                                                .DGNGetShapeFillInfo(elemento);
560

    
561
                                                                // System.err.println("complex shape fill color = "
562
                                                                // + elemento.color);
563
                                                                // }
564
                                                        }
565

    
566
                                                        bConnect = true;
567
                                                } else {
568
                                                        bEsPoligono = false;
569
                                                        bConnect = false;
570
                                                }
571

    
572
                                                break;
573

    
574
                                        case DGNFileHeader.DGNST_MULTIPOINT:
575

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

    
595
                                                if ((psLine.num_vertices == 2)
596
                                                                && (psLine.vertices[0].x == psLine.vertices[1].x)
597
                                                                && (psLine.vertices[0].y == psLine.vertices[1].y)) {
598
                                                        auxRow[ID_FIELD_ENTITY] = "Point";
599
                                                        addShape(
600
                                                                        createPoint3D(psLine.vertices[0].x,
601
                                                                                        psLine.vertices[0].y,
602
                                                                                        psLine.vertices[0].z), auxRow,
603
                                                                        type, dgnReader);
604
                                                } else {
605
                                                        GeneralPathX elShape = new GeneralPathX(
606
                                                                        GeneralPathX.WIND_EVEN_ODD);
607

    
608
                                                        if (psLine.type == DGNFileHeader.DGNT_CURVE) {
609
                                                                psLine.num_vertices = psLine.num_vertices - 4;
610

    
611
                                                                for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) {
612
                                                                        psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
613
                                                                }
614
                                                        }
615

    
616
                                                        if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
617
                                                                        && ((psLine.properties & 0x8000) != 0)) {
618
                                                                // Invertimos el orden porque es un agujero
619
                                                                elShape
620
                                                                                .moveTo(
621
                                                                                                psLine.vertices[psLine.num_vertices - 1].x,
622
                                                                                                psLine.vertices[psLine.num_vertices - 1].y);
623

    
624
                                                                for (int i = psLine.num_vertices - 2; i >= 0; i--) {
625
                                                                        elShape.lineTo(psLine.vertices[i].x,
626
                                                                                        psLine.vertices[i].y);
627
                                                                }
628
                                                        } else {
629
                                                                elShape.moveTo(psLine.vertices[0].x,
630
                                                                                psLine.vertices[0].y);
631

    
632
                                                                for (int i = 1; i < psLine.num_vertices; i++) {
633
                                                                        elShape.lineTo(psLine.vertices[i].x,
634
                                                                                        psLine.vertices[i].y);
635
                                                                }
636
                                                        }
637

    
638
                                                        if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x)
639
                                                                        && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) {
640
                                                                // Lo a?adimos tambi?n como pol?gono
641
                                                                bEsPoligono = true;
642

    
643
                                                                // Miramos si tiene color de relleno
644
                                                                if (elemento.attr_bytes > 0) {
645
                                                                        elemento.color = dgnReader
646
                                                                                        .DGNGetShapeFillInfo(elemento);
647

    
648
                                                                        // System.err.println("fill color = " +
649
                                                                        // elemento.color);
650
                                                                        if (elemento.color != -1) {
651
                                                                                auxRow[ID_FIELD_COLOR] = elemento.color;
652
                                                                        }
653
                                                                }
654

    
655
                                                                if (elemento.complex == 0) {
656
                                                                        addShape(createSurface(elShape), auxRow,
657
                                                                                        type, dgnReader);
658
                                                                }
659
                                                        }
660

    
661
                                                        if (elemento.complex != 0) {
662
                                                                // Si es un agujero o
663
                                                                // es la primera entidad del agujero, lo
664
                                                                // a?adimos sin unir al anterior
665
                                                                if (bFirstHoleEntity
666
                                                                                || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) {
667
                                                                        elementoCompuesto.append(elShape.getPathIterator(null), false);
668
                                                                        bFirstHoleEntity = false;
669
                                                                } else {
670
                                                                        elementoCompuesto.append(elShape.getPathIterator(null), bConnect);
671
                                                                }
672
                                                        } else {
673
                                                                addShape(createMultiCurve(elShape), auxRow,
674
                                                                                type, dgnReader);
675
                                                        }
676
                                                }
677

    
678
                                                break;
679

    
680
                                        case DGNFileHeader.DGNST_ARC:
681

    
682
                                                // dgnReader.DGNDumpElement(dgnReader.getInfo(),
683
                                                // elemento,"");
684
                                                DGNElemArc psArc = (DGNElemArc) elemento;
685

    
686
                                                // La definici?n de arco de MicroStation es distinta a
687
                                                // la de Java.
688
                                                // En el dgn el origin se entiende que es el centro del
689
                                                // arco,
690
                                                // y a la hora de crear un Arc2D las 2 primeras
691
                                                // coordenadas son
692
                                                // la esquina inferior izquierda del rect?ngulo que
693
                                                // rodea al arco.
694
                                                // 1.- Creamos la elipse sin rotaci?n.
695
                                                // 2.- Creamos el arco
696
                                                // 3.- Rotamos el resultado
697

    
698
                                                /*
699
                                                 * System.out.println("Arco con primari axis: " +
700
                                                 * psArc.primary_axis + " start angle: " +
701
                                                 * psArc.startang + " sweepang = " + psArc.sweepang);
702
                                                 * System.out.println("secondaria axis: " +
703
                                                 * psArc.secondary_axis + " rotation = " +
704
                                                 * psArc.rotation);
705
                                                 */
706
                                                AffineTransform mT = AffineTransform.getRotateInstance(
707
                                                                Math.toRadians(psArc.rotation), psArc.origin.x,
708
                                                                psArc.origin.y);
709

    
710
                                                // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
711
                                                Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x
712
                                                                - psArc.primary_axis, psArc.origin.y
713
                                                                - psArc.secondary_axis,
714
                                                                2.0 * psArc.primary_axis,
715
                                                                2.0 * psArc.secondary_axis, -psArc.startang,
716
                                                                -psArc.sweepang, Arc2D.OPEN);
717

    
718
                                                // Ellipse2D.Double elArco = new
719
                                                // Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
720
                                                // psArc.origin.y - psArc.secondary_axis,2.0 *
721
                                                // psArc.primary_axis, 2.0 * psArc.secondary_axis);
722
                                                GeneralPathX elShapeArc = new GeneralPathX(elArco.getPathIterator(null));
723

    
724
                                                // Transformamos el GeneralPahtX porque si transformamos
725
                                                // elArco nos lo convierte
726
                                                // a GeneralPath y nos guarda las coordenadas en float,
727
                                                // con la correspondiente p?rdida de precisi?n
728
                                                elShapeArc.transform(mT);
729

    
730
                                                if (dgnReader.getInfo().dimension == 3) {
731
                                                        // Aqu? podr?amos hacer cosas con la coordenada Z
732
                                                }
733

    
734
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
735
                                                auxRow[ID_FIELD_ENTITY] = "Arc";
736
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
737
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
738

    
739
                                                /*
740
                                                 * Line2D.Double ejeMayor = new
741
                                                 * Line2D.Double(psArc.origin.x - psArc.primary_axis,
742
                                                 * psArc.origin.y, psArc.origin.x + psArc.primary_axis,
743
                                                 * psArc.origin.y);
744
                                                 *
745
                                                 * lyrLines.addShape(new
746
                                                 * FShape(FConstant.SHAPE_TYPE_POLYLINE, new
747
                                                 * GeneralPathX(ejeMayor)), auxRow);
748
                                                 */
749

    
750
                                                // lyrLines.addShape(new
751
                                                // FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
752
                                                // auxRow);
753
                                                if (elemento.complex != 0) {
754
                                                        // Esto es una posible fuente de fallos si detr?s de
755
                                                        // una
756
                                                        // elipse vienen m?s cosas pegadas. Deber?amos
757
                                                        // volver
758
                                                        // a conectar una vez pasada la elipse.
759
                                                        if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
760
                                                                bConnect = false;
761
                                                        }
762

    
763
                                                        // SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
764
                                                        // Y EL ELEMENTO ES UN POLIGONO
765
                                                        if (bFirstHoleEntity
766
                                                                        || ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) {
767
                                                                elementoCompuesto.append(elShapeArc.getPathIterator(null), false);
768
                                                                bFirstHoleEntity = false;
769
                                                        } else {
770
                                                                elementoCompuesto.append(elShapeArc.getPathIterator(null), bConnect);
771
                                                        }
772
                                                } else {
773
                                                        addShape(createMultiCurve(elShapeArc), auxRow,
774
                                                                        type, dgnReader);
775

    
776
                                                        if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
777
                                                                addShape(createSurface(elShapeArc), auxRow,
778
                                                                                type, dgnReader);
779
                                                        }
780
                                                }
781

    
782
                                                // System.err.println("Entra un Arco");
783
                                                break;
784

    
785
                                        case DGNFileHeader.DGNST_TEXT:
786

    
787
                                                DGNElemText psText = (DGNElemText) elemento;
788
                                                Geometry elShapeTxt = createPoint3D(psText.origin.x,
789
                                                                psText.origin.y, psText.origin.z);
790

    
791
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
792
                                                auxRow[ID_FIELD_ENTITY] = "Text";
793
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
794
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
795
                                                auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult;
796
                                                auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation;
797
                                                auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
798
                                                addShape(elShapeTxt, auxRow, type, dgnReader);
799

    
800
                                                // System.out.println("Rotaci?n texto: " +
801
                                                // psText.rotation + "Altura Texto = " + heightText);
802

    
803
                                                /*
804
                                                 * System.out.println("  origin=(" + psText.origin.x +
805
                                                 * ", " + psText.origin.y + ") rotation=" +
806
                                                 * psText.rotation + "\n" + "  font=" + psText.font_id +
807
                                                 * " just=" + psText.justification + "length_mult=" +
808
                                                 * psText.length_mult + " height_mult=" +
809
                                                 * psText.height_mult + "\n" + "  string =" + new
810
                                                 * String(psText.string).toString().trim() + "\n");
811
                                                 */
812
                                                break;
813

    
814
                                        /*
815
                                         * default:
816
                                         * dgnReader.DGNDumpElement(dgnReader.getInfo(),
817
                                         * elemento, "");
818
                                         */
819
                                        } // switch
820
                                } // if
821
                        } // for
822

    
823
                        if (bElementoCompuesto) {
824
                                if (bInsideCell) {
825
                                        auxRow = cellRow;
826
                                } else {
827
                                        auxRow = complexRow;
828
                                }
829

    
830
                                // System.err.println("Entidad compuesta. bInsideCell = " +
831
                                // bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);
832
                                addShape(createMultiCurve(elementoCompuesto), auxRow, type,
833
                                                dgnReader);
834

    
835
                                if (bEsPoligono) {
836
                                        if (complex_index_fill_color != -1) {
837
                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
838
                                        }
839

    
840
                                        addShape(createSurface(elementoCompuesto), auxRow, type,
841
                                                        dgnReader);
842
                                }
843
                        }
844

    
845
                }
846

    
847
                private Geometry createMultiSurface(GeneralPathX elementoCompuesto)
848
                                throws DataException {
849
                        try {
850
                                return geomManager.createMultiSurface(elementoCompuesto,
851
                                                SUBTYPES.GEOM2D);
852
                        } catch (CreateGeometryException e) {
853
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
854
                                                e);
855
                        }
856

    
857
                }
858

    
859
                private Geometry createPoint3D(double x, double y, double z)
860
                                throws DataException {
861
                        Point point;
862
                        try {
863
                                // point = (Point) geomManager.create(TYPES.POINT,
864
                                // SUBTYPES.GEOM3D);
865
                                point = (Point) geomManager.create(TYPES.POINT,
866
                                                SUBTYPES.GEOM3D);
867
                        } catch (CreateGeometryException e) {
868
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
869
                                                e);
870
                        }
871
                        point.setCoordinates(new double[] { x, y, z });
872

    
873
                        return point;
874
                }
875

    
876
                private void addShape(Geometry geometry, Object[] auxRow,
877
                                FeatureType type, DGNReader dgnReader) throws DataException {
878
                        FeatureProvider data = createFeatureProvider(type);
879
                        for (int i=0;i<type.size();i++){
880
                                data.set(i, auxRow[i]);
881
                        }
882
                        data.setDefaultGeometry(geometry);
883
                        addFeatureProvider(data);
884
                        if (this.envelope == null) {
885
                                this.envelope = geometry.getEnvelope();
886
                        } else {
887
                                this.envelope.add(geometry.getEnvelope());
888
                        }
889
                        if (this.leyendBuilder != null) {
890
                                this.leyendBuilder.process(data, dgnReader);
891
                        }
892
                }
893

    
894
                private Geometry createMultiCurve(GeneralPathX elementoCompuesto)
895
                                throws DataException {
896
                        try {
897
                                return geomManager.createMultiCurve(elementoCompuesto,
898
                                                SUBTYPES.GEOM2D);
899
                        } catch (CreateGeometryException e) {
900
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
901
                                                e);
902
                        }
903
                }
904

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

    
915
                }
916

    
917
        }
918

    
919
        public boolean closeResourceRequested(ResourceProvider resource) {
920
                return true;
921
        }
922

    
923
        public int getOIDType() {
924
                return DataTypes.LONG;
925
        }
926

    
927
        public boolean supportsAppendMode() {
928
                return false;
929
        }
930

    
931
        public void append(FeatureProvider featureProvider) {
932
                throw new UnsupportedOperationException();
933
        }
934

    
935
        public void beginAppend() {
936
                throw new UnsupportedOperationException();
937
        }
938

    
939
        public void endAppend() {
940
                throw new UnsupportedOperationException();
941
        }
942

    
943
        public Object createNewOID() {
944
                return new Long(counterNewsOIDs++);
945
        }
946

    
947
        protected void initializeFeatureTypes() throws InitializeException {
948
                try {
949
                        this.open();
950
                } catch (OpenException e) {
951
                        throw new InitializeException(this.getProviderName(), e);
952
                }
953
        }
954

    
955
        public Envelope getEnvelope() throws DataException {
956
                this.open();
957
                return (Envelope) this.getDynValue("Envelope");
958
        }
959

    
960

    
961
        /*
962
         * (non-Javadoc)
963
         *
964
         * @see
965
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
966
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
967
         */
968
        public void resourceChanged(ResourceProvider resource) {
969
                this.getStoreServices().notifyChange(
970
                                DataStoreNotification.RESOURCE_CHANGED,
971
                                resource);
972
        }
973

    
974
        public Object getSourceId() {
975
                return this.getDGNParameters().getFile();
976
        }
977
        
978
        public String getName() {
979
                String name = this.getDGNParameters().getFile().getName();
980
                int n = name.lastIndexOf(".");
981
                if( n<1 ) {
982
                        return name;
983
                }
984
                return name.substring(0, n);
985
        }
986
        
987
        public String getFullName() {
988
                return this.getDGNParameters().getFile().getAbsolutePath();
989
        }
990
        
991
        public ResourceProvider getResource() {
992
                return resource;
993
        }
994

    
995
}