Statistics
| Revision:

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

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
                return true;
144
        }
145

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

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

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

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

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

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

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

    
236
                                                DGNData.legendBuilder = legendBuilder;
237

    
238
                                                DGNData.projection = projection;
239

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

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

    
266

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

    
281
        }
282

    
283

    
284

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

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

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

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

    
317
                public void begin(FeatureStoreProviderServices store) {
318

    
319
                        EditableFeatureType featureType = store.createFeatureType();
320

    
321
                        featureType.setHasOID(true);
322

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

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

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

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

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

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

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

    
368

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

    
376
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
377

    
378

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

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

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

    
389
                }
390

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

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

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

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

    
412
                public void load() throws DataException {
413

    
414
                        this.envelope = null;
415

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
515
                                                break;
516

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

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

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

    
533
                                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
534

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

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

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

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

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

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

    
571
                                                break;
572

    
573
                                        case DGNFileHeader.DGNST_MULTIPOINT:
574

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

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

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

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

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

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

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

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

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

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

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

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

    
677
                                                break;
678

    
679
                                        case DGNFileHeader.DGNST_ARC:
680

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

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

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

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

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

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

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

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

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

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

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

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

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

    
784
                                        case DGNFileHeader.DGNST_TEXT:
785

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

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

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

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

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

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

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

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

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

    
844
                }
845

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

    
856
                }
857

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

    
872
                        return point;
873
                }
874

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

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

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

    
914
                }
915

    
916
        }
917

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

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

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

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

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

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

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

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

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

    
959

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

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

    
994
}