Statistics
| Revision:

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

History | View | Annotate | Download (30.9 KB)

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

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

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

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

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

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

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

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

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

    
107

    
108

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

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

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

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

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

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

    
133
                resource.addConsumer(this);
134

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

    
137

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

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

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

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

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

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

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

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

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

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

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

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

    
258
                                DGNData.legendBuilder = this.legendBuilder;
259

    
260
                                DGNData.projection = this.projection;
261

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

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

    
287

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

    
302
        }
303

    
304

    
305

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

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

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

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

    
338
                public void begin(FeatureStoreProviderServices store) {
339

    
340
                        EditableFeatureType featureType = store.createFeatureType();
341

    
342
                        featureType.setHasOID(true);
343

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

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

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

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

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

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

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

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

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

    
389

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

    
396
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
397

    
398

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

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

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

    
409
                }
410

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

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

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

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

    
432
                public void load() throws DataException {
433

    
434
                        this.envelope = null;
435

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
535
                                                break;
536

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

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

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

    
553
                                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
554

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

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

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

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

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

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

    
591
                                                break;
592

    
593
                                        case DGNFileHeader.DGNST_MULTIPOINT:
594

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

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

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

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

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

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

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

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

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

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

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

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

    
697
                                                break;
698

    
699
                                        case DGNFileHeader.DGNST_ARC:
700

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

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

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

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

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

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

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

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

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

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

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

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

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

    
804
                                        case DGNFileHeader.DGNST_TEXT:
805

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

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

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

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

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

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

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

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

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

    
864
                }
865

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

    
876
                }
877

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

    
892
                        return point;
893
                }
894

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

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

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

    
929
                }
930

    
931
        }
932

    
933
        public boolean closeResourceRequested(ResourceProvider resource) {
934
                return true;
935
        }
936

    
937
        public int getFeatureReferenceOIDType() {
938
                return DataTypes.LONG;
939
        }
940

    
941
        public boolean supportsAppendMode() {
942
                return false;
943
        }
944

    
945
        public void append(FeatureData featureData) {
946
                // FIXME Exception
947
                throw new UnsupportedOperationException();
948
        }
949

    
950
        public void beginAppend() {
951
                // FIXME Exception
952
                throw new UnsupportedOperationException();
953
        }
954

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

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

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

    
970
        public Object createNewOID() {
971
                return new Long(counterNewsOIDs++);
972
        }
973

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

    
982
        public Envelope getEnvelope() throws DataException {
983
                this.open();
984
                return (Envelope) this.dynObject.getDynValue("Envelope");
985
        }
986

    
987
        public Iterator getChilds() {
988
                // TODO Auto-generated method stub
989
                return null;
990
        }
991

    
992

    
993
        /*
994
         * (non-Javadoc)
995
         *
996
         * @see
997
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
998
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
999
         */
1000
        public void resourceChanged(ResourceProvider resource) {
1001
                this.store.notifyChange(DataStoreNotification.RESOURCE_CHANGED,
1002
                                resource);
1003
        }
1004

    
1005
        protected static void registerDynClass() {
1006
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
1007
                DynClass dynClass;
1008
                DynField field;
1009
                if (DYNCLASS == null) {
1010
                        dynClass = dynman.add(DYNCLASS_NAME, "DGN File Store");
1011
                        dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
1012

    
1013
                        DYNCLASS = dynClass;
1014
                }
1015

    
1016
        }
1017

    
1018
        public Object getSourceId() {
1019
                return this.getParameters().getFile();
1020
        }
1021

    
1022
}