Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dgn / DGNReader.java @ 1172

History | View | Annotate | Download (99.1 KB)

1
/*
2
 * Created on 14-jun-2004
3
 *
4
 * TODO To change the template for this generated file go to
5
 * Window - Preferences - Java - Code Generation - Code and Comments
6
 */
7
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
8
 *
9
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
10
 *
11
 * This program is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU General Public License
13
 * as published by the Free Software Foundation; either version 2
14
 * of the License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
24
 *
25
 * For more information, contact:
26
 *
27
 *  Generalitat Valenciana
28
 *   Conselleria d'Infraestructures i Transport
29
 *   Av. Blasco Ib??ez, 50
30
 *   46010 VALENCIA
31
 *   SPAIN
32
 *
33
 *      +34 963862235
34
 *   gvsig@gva.es
35
 *      www.gvsig.gva.es
36
 *
37
 *    or
38
 *
39
 *   IVER T.I. S.A
40
 *   Salamanca 50
41
 *   46005 Valencia
42
 *   Spain
43
 *
44
 *   +34 963163400
45
 *   dac@iver.es
46
 */
47
package com.iver.cit.gvsig.fmap.drivers.dgn;
48

    
49
import java.awt.Color;
50
import java.awt.geom.Rectangle2D;
51

    
52
import java.io.FileInputStream;
53

    
54
import java.nio.ByteOrder;
55
import java.nio.MappedByteBuffer;
56
import java.nio.channels.FileChannel;
57

    
58

    
59
/**
60
 * Clase dedicada a leer del fichero DGN.
61
 *
62
 * @author FJP
63
 */
64
public class DGNReader {
65
        // private static Logger logger = Logger.getLogger(DGNReader.class.getName());
66
        static int[][] abyDefaultPCT = {
67
                        { 255, 255, 255 },
68
                        { 0, 0, 255 },
69
                        { 0, 255, 0 },
70
                        { 255, 0, 0 },
71
                        { 255, 255, 0 },
72
                        { 255, 0, 255 },
73
                        { 255, 127, 0 },
74
                        { 0, 255, 255 },
75
                        { 64, 64, 64 },
76
                        { 192, 192, 192 },
77
                        { 254, 0, 96 },
78
                        { 160, 224, 0 },
79
                        { 0, 254, 160 },
80
                        { 128, 0, 160 },
81
                        { 176, 176, 176 },
82
                        { 0, 240, 240 },
83
                        { 240, 240, 240 },
84
                        { 0, 0, 240 },
85
                        { 0, 240, 0 },
86
                        { 240, 0, 0 },
87
                        { 240, 240, 0 },
88
                        { 240, 0, 240 },
89
                        { 240, 122, 0 },
90
                        { 0, 240, 240 },
91
                        { 240, 240, 240 },
92
                        { 0, 0, 240 },
93
                        { 0, 240, 0 },
94
                        { 240, 0, 0 },
95
                        { 240, 240, 0 },
96
                        { 240, 0, 240 },
97
                        { 240, 122, 0 },
98
                        { 0, 225, 225 },
99
                        { 225, 225, 225 },
100
                        { 0, 0, 225 },
101
                        { 0, 225, 0 },
102
                        { 225, 0, 0 },
103
                        { 225, 225, 0 },
104
                        { 225, 0, 225 },
105
                        { 225, 117, 0 },
106
                        { 0, 225, 225 },
107
                        { 225, 225, 225 },
108
                        { 0, 0, 225 },
109
                        { 0, 225, 0 },
110
                        { 225, 0, 0 },
111
                        { 225, 225, 0 },
112
                        { 225, 0, 225 },
113
                        { 225, 117, 0 },
114
                        { 0, 210, 210 },
115
                        { 210, 210, 210 },
116
                        { 0, 0, 210 },
117
                        { 0, 210, 0 },
118
                        { 210, 0, 0 },
119
                        { 210, 210, 0 },
120
                        { 210, 0, 210 },
121
                        { 210, 112, 0 },
122
                        { 0, 210, 210 },
123
                        { 210, 210, 210 },
124
                        { 0, 0, 210 },
125
                        { 0, 210, 0 },
126
                        { 210, 0, 0 },
127
                        { 210, 210, 0 },
128
                        { 210, 0, 210 },
129
                        { 210, 112, 0 },
130
                        { 0, 195, 195 },
131
                        { 195, 195, 195 },
132
                        { 0, 0, 195 },
133
                        { 0, 195, 0 },
134
                        { 195, 0, 0 },
135
                        { 195, 195, 0 },
136
                        { 195, 0, 195 },
137
                        { 195, 107, 0 },
138
                        { 0, 195, 195 },
139
                        { 195, 195, 195 },
140
                        { 0, 0, 195 },
141
                        { 0, 195, 0 },
142
                        { 195, 0, 0 },
143
                        { 195, 195, 0 },
144
                        { 195, 0, 195 },
145
                        { 195, 107, 0 },
146
                        { 0, 180, 180 },
147
                        { 180, 180, 180 },
148
                        { 0, 0, 180 },
149
                        { 0, 180, 0 },
150
                        { 180, 0, 0 },
151
                        { 180, 180, 0 },
152
                        { 180, 0, 180 },
153
                        { 180, 102, 0 },
154
                        { 0, 180, 180 },
155
                        { 180, 180, 180 },
156
                        { 0, 0, 180 },
157
                        { 0, 180, 0 },
158
                        { 180, 0, 0 },
159
                        { 180, 180, 0 },
160
                        { 180, 0, 180 },
161
                        { 180, 102, 0 },
162
                        { 0, 165, 165 },
163
                        { 165, 165, 165 },
164
                        { 0, 0, 165 },
165
                        { 0, 165, 0 },
166
                        { 165, 0, 0 },
167
                        { 165, 165, 0 },
168
                        { 165, 0, 165 },
169
                        { 165, 97, 0 },
170
                        { 0, 165, 165 },
171
                        { 165, 165, 165 },
172
                        { 0, 0, 165 },
173
                        { 0, 165, 0 },
174
                        { 165, 0, 0 },
175
                        { 165, 165, 0 },
176
                        { 165, 0, 165 },
177
                        { 165, 97, 0 },
178
                        { 0, 150, 150 },
179
                        { 150, 150, 150 },
180
                        { 0, 0, 150 },
181
                        { 0, 150, 0 },
182
                        { 150, 0, 0 },
183
                        { 150, 150, 0 },
184
                        { 150, 0, 150 },
185
                        { 150, 92, 0 },
186
                        { 0, 150, 150 },
187
                        { 150, 150, 150 },
188
                        { 0, 0, 150 },
189
                        { 0, 150, 0 },
190
                        { 150, 0, 0 },
191
                        { 150, 150, 0 },
192
                        { 150, 0, 150 },
193
                        { 150, 92, 0 },
194
                        { 0, 135, 135 },
195
                        { 135, 135, 135 },
196
                        { 0, 0, 135 },
197
                        { 0, 135, 0 },
198
                        { 135, 0, 0 },
199
                        { 135, 135, 0 },
200
                        { 135, 0, 135 },
201
                        { 135, 87, 0 },
202
                        { 0, 135, 135 },
203
                        { 135, 135, 135 },
204
                        { 0, 0, 135 },
205
                        { 0, 135, 0 },
206
                        { 135, 0, 0 },
207
                        { 135, 135, 0 },
208
                        { 135, 0, 135 },
209
                        { 135, 87, 0 },
210
                        { 0, 120, 120 },
211
                        { 120, 120, 120 },
212
                        { 0, 0, 120 },
213
                        { 0, 120, 0 },
214
                        { 120, 0, 0 },
215
                        { 120, 120, 0 },
216
                        { 120, 0, 120 },
217
                        { 120, 82, 0 },
218
                        { 0, 120, 120 },
219
                        { 120, 120, 120 },
220
                        { 0, 0, 120 },
221
                        { 0, 120, 0 },
222
                        { 120, 0, 0 },
223
                        { 120, 120, 0 },
224
                        { 120, 0, 120 },
225
                        { 120, 82, 0 },
226
                        { 0, 105, 105 },
227
                        { 105, 105, 105 },
228
                        { 0, 0, 105 },
229
                        { 0, 105, 0 },
230
                        { 105, 0, 0 },
231
                        { 105, 105, 0 },
232
                        { 105, 0, 105 },
233
                        { 105, 77, 0 },
234
                        { 0, 105, 105 },
235
                        { 105, 105, 105 },
236
                        { 0, 0, 105 },
237
                        { 0, 105, 0 },
238
                        { 105, 0, 0 },
239
                        { 105, 105, 0 },
240
                        { 105, 0, 105 },
241
                        { 105, 77, 0 },
242
                        { 0, 90, 90 },
243
                        { 90, 90, 90 },
244
                        { 0, 0, 90 },
245
                        { 0, 90, 0 },
246
                        { 90, 0, 0 },
247
                        { 90, 90, 0 },
248
                        { 90, 0, 90 },
249
                        { 90, 72, 0 },
250
                        { 0, 90, 90 },
251
                        { 90, 90, 90 },
252
                        { 0, 0, 90 },
253
                        { 0, 90, 0 },
254
                        { 90, 0, 0 },
255
                        { 90, 90, 0 },
256
                        { 90, 0, 90 },
257
                        { 90, 72, 0 },
258
                        { 0, 75, 75 },
259
                        { 75, 75, 75 },
260
                        { 0, 0, 75 },
261
                        { 0, 75, 0 },
262
                        { 75, 0, 0 },
263
                        { 75, 75, 0 },
264
                        { 75, 0, 75 },
265
                        { 75, 67, 0 },
266
                        { 0, 75, 75 },
267
                        { 75, 75, 75 },
268
                        { 0, 0, 75 },
269
                        { 0, 75, 0 },
270
                        { 75, 0, 0 },
271
                        { 75, 75, 0 },
272
                        { 75, 0, 75 },
273
                        { 75, 67, 0 },
274
                        { 0, 60, 60 },
275
                        { 60, 60, 60 },
276
                        { 0, 0, 60 },
277
                        { 0, 60, 0 },
278
                        { 60, 0, 0 },
279
                        { 60, 60, 0 },
280
                        { 60, 0, 60 },
281
                        { 60, 62, 0 },
282
                        { 0, 60, 60 },
283
                        { 60, 60, 60 },
284
                        { 0, 0, 60 },
285
                        { 0, 60, 0 },
286
                        { 60, 0, 0 },
287
                        { 60, 60, 0 },
288
                        { 60, 0, 60 },
289
                        { 60, 62, 0 },
290
                        { 0, 45, 45 },
291
                        { 45, 45, 45 },
292
                        { 0, 0, 45 },
293
                        { 0, 45, 0 },
294
                        { 45, 0, 0 },
295
                        { 45, 45, 0 },
296
                        { 45, 0, 45 },
297
                        { 45, 57, 0 },
298
                        { 0, 45, 45 },
299
                        { 45, 45, 45 },
300
                        { 0, 0, 45 },
301
                        { 0, 45, 0 },
302
                        { 45, 0, 0 },
303
                        { 45, 45, 0 },
304
                        { 45, 0, 45 },
305
                        { 45, 57, 0 },
306
                        { 0, 30, 30 },
307
                        { 30, 30, 30 },
308
                        { 0, 0, 30 },
309
                        { 0, 30, 0 },
310
                        { 30, 0, 0 },
311
                        { 30, 30, 0 },
312
                        { 30, 0, 30 },
313
                        { 30, 52, 0 },
314
                        { 0, 30, 30 },
315
                        { 30, 30, 30 },
316
                        { 0, 0, 30 },
317
                        { 0, 30, 0 },
318
                        { 30, 0, 0 },
319
                        { 30, 30, 0 },
320
                        { 30, 0, 30 },
321
                        { 192, 192, 192 },
322
                        { 28, 0, 100 }
323
                };
324
        private int LSB;
325
        private FileInputStream fin;
326

    
327
        // private LEDataInputStream input;
328
        private MappedByteBuffer bb;
329
        private int FALSE = 0;
330
        private int TRUE = 1;
331
        private DGNElemCore elemento;
332
        private DGNInfo info; // Contiene el path y otras cosas
333
        private Rectangle2D.Double m_BoundingBox;
334
        private DGNElemColorTable m_colorTable;
335

    
336
        /**
337
         * Crea un nuevo DGNReader.
338
         *
339
         * @param pathFich DOCUMENT ME!
340
         */
341
        public DGNReader(String pathFich) {
342
                info = new DGNInfo();
343

    
344
                DGNElemCore elemento = new DGNElemCore();
345
                int iArg;
346
                int bReportExtents = 0;
347
                byte[] achRaw = new byte[64];
348
                achRaw[63] = 1;
349

    
350
                double dfSFXMin = 0.0;
351
                double dfSFXMax = 0.0;
352
                double dfSFYMin = 0.0;
353
                double dfSFYMax = 0.0;
354

    
355
                info.fp = pathFich;
356
                info = DGNOpen(info, 0);
357

    
358
                bb.rewind();
359
                DGNSetSpatialFilter(info, dfSFXMin, dfSFYMin, dfSFXMax, dfSFYMax);
360

    
361
                int nLevel;
362
                int nType;
363
                int[] anLevelTypeCount = new int[128 * 64];
364
                int[] anLevelCount = new int[64];
365
                int[] anTypeCount = new int[128];
366
                double[] adfExtents = new double[6];
367
                int[] nCount = new int[1];
368
                nCount[0] = 0;
369

    
370
                DGNGetExtents(info, adfExtents); //extender
371
                System.out.println("X Range:" + adfExtents[0] + ", " + adfExtents[3]);
372
                System.out.println("Y Range:" + adfExtents[1] + ", " + adfExtents[4]);
373
                System.out.println("Z Range:" + adfExtents[2] + ", " + adfExtents[5]);
374

    
375
                m_BoundingBox = new Rectangle2D.Double();
376
                m_BoundingBox.setRect(adfExtents[0], adfExtents[1],
377
                        (adfExtents[3] - adfExtents[0]), (adfExtents[4] - adfExtents[1]));
378

    
379
                /* m_Renderer = new FRenderer(this); */
380
                DGNElementInfo[] pasEI; //=new DGNElementInfo[nCount+1];
381
                pasEI = DGNGetElementIndex(info, nCount);
382

    
383
                System.out.println("Total Elements:" + nCount[0]);
384

    
385
                for (int i = 0; i < nCount[0]; i++) {
386
                        anLevelTypeCount[(pasEI[i].level * 128) + pasEI[i].type]++;
387
                        anLevelCount[pasEI[i].level]++;
388
                        anTypeCount[pasEI[i].type]++;
389
                }
390

    
391
                ////System.out.println("\n");
392
                System.out.println("Per Type Report\n");
393
                System.out.println("===============\n");
394

    
395
                for (nType = 0; nType < 128; nType++) {
396
                        if (anTypeCount[nType] != 0) {
397
                                System.out.println("Type:" + DGNTypeToName(nType) + ":" +
398
                                        anTypeCount[nType] + "\n");
399
                        }
400
                }
401

    
402
                //System.out.println("\n");
403
                //System.out.println("Per Level Report\n");
404
                //System.out.println("================\n");
405
                for (nLevel = 0; nLevel < 64; nLevel++) {
406
                        if (anLevelCount[nLevel] == 0) {
407
                                continue;
408
                        }
409

    
410
                        //System.out.println("Level " + nLevel + "," + anLevelCount[nLevel] +"elements:\n");
411
                        for (nType = 0; nType < 128; nType++) {
412
                                if (anLevelTypeCount[(nLevel * 128) + nType] != 0) {
413
                                        //System.out.println("  Type " + DGNTypeToName(nType) + ","anLevelTypeCount[(nLevel * 128) + nType] + "\n");
414
                                }
415
                        }
416

    
417
                        //System.out.println("\n");
418
                }
419

    
420
                bb.rewind();
421
        }
422

    
423
        /* public Color getColor(int indexColor)
424
           {
425
                   int r,g,b;
426
                   // System.err.println("indexcolor = " + indexColor);
427
                   // Si no hay tabla de colores, interpretamos que todas las cosas son negras
428
                   if (m_colorTable == null) return new Color(0,0,0);
429
        
430
                   r = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][0]);
431
                   g = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][1]);
432
                   b = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][2]);
433
        
434
                   if ((r==255) && (g==255) & (b==255))
435
                   {
436
                           r=g=b=0; // El color blanco lo devolvemos como negro.
437
                   }
438
        
439
                   return new Color(r,g,b);
440
           } */
441

    
442
        /**
443
         * Devuelve la informaci?n del DGN.
444
         *
445
         * @return DGNInfo Informaci?n.
446
         */
447
        public DGNInfo getInfo() {
448
                return info;
449
        }
450

    
451
        /**
452
         * Devuelve el n?mero de elementos.
453
         *
454
         * @return N?mero de elementos.
455
         */
456
        public int getNumEntities() {
457
                return info.element_count;
458
        }
459

    
460
        /**
461
         * Devuelve el rect?ngulo del extent.
462
         *
463
         * @return Rect?ngulo.
464
         */
465
        public Rectangle2D getBoundingBox() {
466
                return m_BoundingBox;
467
        }
468

    
469
        /************************************************************************/
470
        /*                           DGNGotoElement()                           */
471
        /************************************************************************/
472

    
473
        /**
474
         * Seek to indicated element. Changes what element will be read on the next
475
         * call to DGNReadElement().  Note that this function requires and index,
476
         * and one will be built if not already available.
477
         *
478
         * @param element_id the element to seek to.  These values are sequentially
479
         *                   ordered starting at zero for the first element.
480
         *
481
         * @return returns TRUE on success or FALSE on failure.
482
         */
483
        public int DGNGotoElement(int element_id) {
484
                DGNBuildIndex(info);
485

    
486
                if ((element_id < 0) || (element_id >= info.element_count)) {
487
                        return FALSE;
488
                }
489

    
490
                // System.out.println("Posicionamos en " + info.element_index[element_id].offset);
491
                bb.position((int) info.element_index[element_id].offset);
492

    
493
                info.next_element_id = element_id;
494
                info.in_complex_group = FALSE;
495

    
496
                return TRUE;
497
        }
498

    
499
        /**
500
         * DGNOpen
501
         *
502
         * @param info DOCUMENT ME!
503
         * @param bUpdate DOCUMENT ME!
504
         *
505
         * @return DOCUMENT ME!
506
         */
507
        private DGNInfo DGNOpen(DGNInfo info, int bUpdate) {
508
                int pos = 0;
509
                byte[] abyHeader = new byte[512];
510
                info.next_element_id = 0;
511
                info.got_tcb = FALSE;
512
                info.scale = 1.0;
513
                info.origin_x = 0.0;
514
                info.origin_y = 0.0;
515
                info.origin_z = 0.0;
516
                info.index_built = FALSE;
517
                info.element_count = 0;
518
                info.element_index = null;
519
                info.got_bounds = FALSE;
520

    
521
                try {
522
                        fin = new FileInputStream(info.fp);
523

    
524
                        FileChannel fc = fin.getChannel();
525

    
526
                        long sz = fc.size();
527
                        int numReg;
528

    
529
                        // Get the file's size and then map it into memory
530
                        bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
531
                        bb.order(ByteOrder.nativeOrder());
532
                        bb.get(abyHeader, pos, abyHeader.length);
533

    
534
                        info.ftall = (int) (sz / 16);
535

    
536
                        if (bb.order() == ByteOrder.LITTLE_ENDIAN) {
537
                                LSB = TRUE;
538
                        }
539

    
540
                        if (DGNTestOpen(abyHeader, abyHeader.length) != FALSE) {
541
                                if (abyHeader[0] == (byte) 0xC8) {
542
                                        info.dimension = 3; //0xC8
543
                                } else {
544
                                        info.dimension = 2;
545
                                }
546

    
547
                                info.has_spatial_filter = FALSE;
548
                                info.sf_converted_to_uor = FALSE;
549
                                info.select_complex_group = FALSE;
550
                                info.in_complex_group = FALSE;
551
                        }
552

    
553
                        // fin.close();
554
                } catch (Exception e) {
555
                        // logger.debug(e);
556
                        e.printStackTrace();
557
                }
558

    
559
                return info;
560
        }
561

    
562
        /**
563
         * Comprobaci?n si se puede abrir el fichero.
564
         *
565
         * @param pabyHeader Vector byte con el header.
566
         * @param nByteCount n?mero de bytes.
567
         *
568
         * @return Devuelve un enteor que muestra si no hay errores.
569
         */
570
        private int DGNTestOpen(byte[] pabyHeader, int nByteCount) {
571
                if (nByteCount < 4) {
572
                        return TRUE;
573
                }
574

    
575
                // Is it a cell library?
576
                if ((pabyHeader[0] == (byte) 0x08) && (pabyHeader[1] == (byte) 0x05) &&
577
                                (pabyHeader[2] == (byte) 0x17) &&
578
                                (pabyHeader[3] == (byte) 0x00)) {
579
                        return TRUE;
580
                }
581

    
582
                // Is it not a regular 2D or 3D file?
583
                if (((pabyHeader[0] != (byte) 0x08) && (pabyHeader[0] != (byte) 0xC8)) ||
584
                                (pabyHeader[1] != (byte) 0x09) ||
585
                                (pabyHeader[2] != (byte) 0xFE) ||
586
                                (pabyHeader[3] != (byte) 0x02)) {
587
                        return FALSE;
588
                }
589

    
590
                return TRUE;
591
        }
592

    
593
        /**
594
         * Lee una fila del elemento.
595
         *
596
         * @param info Informaci?n del DGN.
597
         * @param core Elemento.
598
         *
599
         * @return Devuelve un entero que muestra si se ha calculado correctamente.
600
         */
601
        private int DGNLoadRawElement(DGNInfo info, DGNElemCore core) {
602
                /* -------------------------------------------------------------------- */
603
                /*      Read the first four bytes to get the level, type, and word      */
604
                /*      count.                                                          */
605
                /* -------------------------------------------------------------------- */
606

    
607
                //int                nType, nWords, nLevel;
608
                int nType = 0;
609
                int nWords = 0;
610
                int nLevel = 0;
611

    
612
                try {
613
                        //input=new LEDataInputStream(fin);
614
                        // System.out.println("info.ftall" + info.ftall + " bb.position() = " + bb.position());
615
                        for (int i = 0; i < 4; i++) {
616
                                info.abyElem[i] = bb.get();
617

    
618
                                //info.temporal[i]=input.readByte();
619
                        }
620

    
621
                        ////System.out.println(ByteUtils.byteToUnsignedInt(info.abyElem[2])+";"+ByteUtils.byteToUnsignedInt(info.abyElem[3]));
622
                        if ((info.abyElem[0] == -1) && (info.abyElem[1] == -1)) {
623
                                return FALSE;
624
                        }
625

    
626
                        nWords = ByteUtils.byteToUnsignedInt(info.abyElem[2]) +
627
                                (ByteUtils.byteToUnsignedInt(info.abyElem[3]) * 256);
628
                        nType = ByteUtils.byteToUnsignedInt(info.abyElem[1]) & 0x7f;
629
                        nLevel = ByteUtils.byteToUnsignedInt(info.abyElem[0]) & 0x3f;
630

    
631
                        /* -------------------------------------------------------------------- */
632
                        /*      Read the rest of the element data into the working buffer.      */
633
                        /* -------------------------------------------------------------------- */
634
                        if (((nWords * 2) + 4) > info.abyElem.length) {
635
                                return FALSE;
636
                        }
637

    
638
                        //CPLAssert( nWords * 2 + 4 <= (int) sizeof(psDGN->abyElem) );
639
                        //byte[] temp = new byte[131072];
640
                        ////System.out.println(nWords);
641
                        for (int i = 0; i < (nWords * 2); i++) {
642
                                info.abyElem[i + 4] = bb.get();
643
                        }
644

    
645
                        //        input.close();
646
                        /* -------------------------------------------------------------------- */
647
                        /*      Read the rest of the element data into the working buffer.      */
648
                        /* -------------------------------------------------------------------- */
649
                        /*     CPLAssert( nWords * 2 + 4 <= (int) sizeof(psDGN->abyElem) );
650
                           if( (int) VSIFRead( psDGN->abyElem + 4, 2, nWords, psDGN->fp ) != nWords )
651
                               return FALSE; */
652
                        info.ftall = bb.position();
653
                } catch (Exception e) {
654
                        // logger.debug(e);
655
                        System.err.println("Error al leer: nWords = " + nWords);
656
                        System.err.println("info.abyElem.length =  " + info.abyElem.length);
657
                        System.err.println("bb.position() =  " + bb.position());
658
                        e.printStackTrace();
659

    
660
                        return FALSE;
661
                }
662

    
663
                info.nElemBytes = (nWords * 2) + 4;
664
                info.next_element_id++;
665

    
666
                /* -------------------------------------------------------------------- */
667
                /*      Return requested info.                                          */
668
                /* -------------------------------------------------------------------- */
669
                //if( core.type != null )
670
                core.type = nType;
671

    
672
                //if( core.level != null )
673
                core.level = nLevel;
674

    
675
                return TRUE;
676
        }
677

    
678
        /**
679
         * Calcula el filtro espacial al rect?ngulo del elemento.
680
         *
681
         * @param info Informaci?n del DGN.
682
         */
683
        private void DGNSpatialFilterToUOR(DGNInfo info) {
684
                DGNPoint sMin = new DGNPoint();
685
                DGNPoint sMax = new DGNPoint();
686

    
687
                if ((info.sf_converted_to_uor == 1) ||
688
                                (!(info.has_spatial_filter == 1)) || (!(info.got_tcb == 1))) {
689
                        return;
690
                }
691

    
692
                sMin.x = info.sf_min_x_geo;
693
                sMin.y = info.sf_min_y_geo;
694
                sMin.z = 0;
695

    
696
                sMax.x = info.sf_max_x_geo;
697
                sMax.y = info.sf_max_y_geo;
698
                sMax.z = 0;
699

    
700
                DGNInverseTransformPoint(info, sMin);
701
                DGNInverseTransformPoint(info, sMax);
702

    
703
                info.sf_min_x = (long) (sMin.x + 2147483648.0);
704
                info.sf_min_y = (long) (sMin.y + 2147483648.0);
705
                info.sf_max_x = (long) (sMax.x + 2147483648.0);
706
                info.sf_max_y = (long) (sMax.y + 2147483648.0);
707

    
708
                info.sf_converted_to_uor = TRUE;
709
        }
710

    
711
        /**
712
         * Calcula un punto aplicandole la transformaci?n.
713
         *
714
         * @param info Informaci?n del DGN.
715
         * @param punto Punto.
716
         */
717
        private void DGNInverseTransformPoint(DGNInfo info, DGNPoint punto) {
718
                punto.x = (punto.x + info.origin_x) / info.scale;
719
                punto.y = (punto.y + info.origin_y) / info.scale;
720
                punto.z = (punto.z + info.origin_z) / info.scale;
721

    
722
                punto.x = Math.max(-2147483647, Math.min(2147483647, punto.x));
723
                punto.y = Math.max(-2147483647, Math.min(2147483647, punto.y));
724
                punto.z = Math.max(-2147483647, Math.min(2147483647, punto.z));
725
        }
726

    
727
        /**
728
         * DOCUMENT ME!
729
         *
730
         * @return DOCUMENT ME!
731
         */
732
        public DGNElemCore DGNReadElement() {
733
                DGNElemCore elemento = new DGNElemCore();
734
                int nType;
735
                int nLevel;
736
                int bInsideFilter;
737

    
738
                /* -------------------------------------------------------------------- */
739
                /*      Load the element data into the current buffer.  If a spatial    */
740
                /*      filter is in effect, loop until we get something within our     */
741
                /*      spatial constraints.                                            */
742
                /* -------------------------------------------------------------------- */
743
                do {
744
                        bInsideFilter = TRUE;
745

    
746
                        int fin_fichero = DGNLoadRawElement(info, elemento);
747

    
748
                        if (fin_fichero == FALSE) {
749
                                return null;
750
                        }
751

    
752
                        if (info.has_spatial_filter != FALSE) {
753
                                //long        nXMin, nXMax, nYMin, nYMax;
754
                                if (info.sf_converted_to_uor == FALSE) {
755
                                        DGNSpatialFilterToUOR(info);
756
                                }
757

    
758
                                if (DGNGetRawExtents(info, null, elemento) == null) {
759
                                        bInsideFilter = TRUE;
760
                                } else if ((info.min_x > info.sf_max_x) ||
761
                                                (info.min_y > info.sf_max_y) ||
762
                                                (info.max_x < info.sf_min_x) ||
763
                                                (info.max_y < info.sf_min_y)) {
764
                                        bInsideFilter = FALSE;
765
                                }
766

    
767
                                if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER) ||
768
                                                (elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)) {
769
                                        info.in_complex_group = TRUE;
770
                                        info.select_complex_group = bInsideFilter;
771
                                } else if ((info.abyElem[0] & (byte) 0x80) != FALSE) {
772
                                        if (info.in_complex_group == TRUE) {
773
                                                bInsideFilter = info.select_complex_group;
774
                                        }
775
                                } else {
776
                                        info.in_complex_group = FALSE;
777
                                }
778
                        }
779
                } while (bInsideFilter == FALSE);
780

    
781
                elemento = DGNProcessElement(info, elemento.type, elemento.level);
782

    
783
                return elemento;
784
        }
785

    
786
        /**
787
         * Devuelve los extent de una fila.
788
         *
789
         * @param info Informaci?n del DGN.
790
         * @param pabyRawData Vector de byte.
791
         * @param elemento Elemento.
792
         *
793
         * @return Vector de double.
794
         */
795
        public double[] DGNGetRawExtents(DGNInfo info, byte[] pabyRawData,
796
                DGNElemCore elemento) {
797
                //byte[] pabyRawData = new byte[info.abyElem.length];
798
                if (pabyRawData == null) {
799
                        pabyRawData = info.abyElem;
800
                }
801

    
802
                double[] tempo = new double[6];
803

    
804
                switch (elemento.type) {
805
                        case DGNFileHeader.DGNT_LINE:
806
                        case DGNFileHeader.DGNT_LINE_STRING:
807
                        case DGNFileHeader.DGNT_SHAPE:
808
                        case DGNFileHeader.DGNT_CURVE:
809
                        case DGNFileHeader.DGNT_BSPLINE:
810
                        case DGNFileHeader.DGNT_ELLIPSE:
811
                        case DGNFileHeader.DGNT_ARC:
812
                        case DGNFileHeader.DGNT_TEXT:
813
                        case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
814
                        case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
815

    
816
                                byte[] temp = new byte[4];
817
                                System.arraycopy(pabyRawData, 4, temp, 0, 4);
818
                                tempo[0] = DGN_INT32(temp); //4
819

    
820
                                System.arraycopy(pabyRawData, 8, temp, 0, 4);
821
                                tempo[1] = DGN_INT32(temp);
822

    
823
                                System.arraycopy(pabyRawData, 12, temp, 0, 4);
824
                                tempo[2] = DGN_INT32(temp);
825

    
826
                                System.arraycopy(pabyRawData, 16, temp, 0, 4);
827
                                tempo[3] = DGN_INT32(temp);
828

    
829
                                System.arraycopy(pabyRawData, 20, temp, 0, 4);
830
                                tempo[4] = DGN_INT32(temp);
831

    
832
                                System.arraycopy(pabyRawData, 24, temp, 0, 4);
833
                                tempo[5] = DGN_INT32(temp);
834

    
835
                                // System.out.println("tempo = " + tempo[0] + " " + tempo[1] + " " + tempo[2]);
836
                                return tempo;
837

    
838
                        default:
839
                                return null;
840
                }
841
        }
842

    
843
        /**
844
         * A partir de un vector de byte devuelve un double.
845
         *
846
         * @param p Vector de byte.
847
         *
848
         * @return double.
849
         */
850
        private double DGN_INT32(byte[] p) {
851
                int x = 256;
852
                int x0;
853
                int x1;
854
                int x2;
855
                int x3;
856
                x0 = (int) p[0];
857
                x1 = (int) p[1];
858
                x2 = (int) p[2];
859
                x3 = (int) p[3];
860

    
861
                if (p[0] < 0) {
862
                        x0 = x + (int) p[0];
863
                }
864

    
865
                if (p[1] < 0) {
866
                        x1 = x + (int) p[1];
867
                }
868

    
869
                if (p[2] < 0) {
870
                        x2 = x + (int) p[2];
871
                }
872

    
873
                if (p[3] < 0) {
874
                        x3 = x + (int) p[3];
875
                }
876

    
877
                return (x2 + (x3 * 256) + (x1 * 65536 * 256) + (x0 * 65536));
878
        }
879

    
880
        /**
881
         * DOCUMENT ME!
882
         *
883
         * @param info DOCUMENT ME!
884
         * @param nType DOCUMENT ME!
885
         * @param nLevel DOCUMENT ME!
886
         *
887
         * @return DOCUMENT ME!
888
         */
889
        private DGNElemCore DGNProcessElement(DGNInfo info, int nType, int nLevel) {
890
                DGNElemCore elemento = new DGNElemCore();
891

    
892
                // if (info.next_element_id < 100)
893
                //         System.out.println("nType = " + nType);       
894
                switch (nType) {
895
                        case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
896
                                System.err.println(DGNTypeToName(nType));
897
                                elemento.stype = DGNFileHeader.DGNST_SHARED_CELL_DEFN;
898
                                DGNParseCore(info, elemento);
899

    
900
                                break;
901

    
902
                        case DGNFileHeader.DGNT_CELL_HEADER: {
903
                                // System.err.println("DGNT_CELL_HEADER");
904
                                DGNElemCellHeader psCell = new DGNElemCellHeader();
905
                                psCell.stype = DGNFileHeader.DGNST_CELL_HEADER;
906
                                DGNParseCore(info, psCell);
907
                                psCell.totlength = ByteUtils.getUnsigned(info.abyElem[36]) +
908
                                        (ByteUtils.getUnsigned(info.abyElem[37]) * 256);
909

    
910
                                byte[] temp = new byte[psCell.name.length];
911
                                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
912
                                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[38]) +
913
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256), temp);
914

    
915
                                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length -
916
                                        3); //esta linea puede tener problemas.
917
                                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[40]) +
918
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256), temp);
919
                                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42]) +
920
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
921
                                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44]) +
922
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
923
                                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46]) +
924
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
925
                                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48]) +
926
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
927
                                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50]) +
928
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
929
                                psCell.color = info.abyElem[35];
930

    
931
                                if (info.dimension == 2) {
932
                                        byte[] temp1 = new byte[4];
933
                                        System.arraycopy(info.abyElem, 52, temp1, 0, 4);
934
                                        psCell.rnglow.x = DGN_INT32(temp1);
935
                                        System.arraycopy(info.abyElem, 56, temp1, 0, 4);
936
                                        psCell.rnglow.y = DGN_INT32(temp);
937
                                        System.arraycopy(info.abyElem, 60, temp1, 0, 4);
938
                                        psCell.rnghigh.x = DGN_INT32(temp1);
939
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 4);
940
                                        psCell.rnghigh.y = DGN_INT32(temp1);
941
                                        System.arraycopy(info.abyElem, 84, temp1, 0, 4);
942
                                        psCell.origin.x = DGN_INT32(temp1);
943
                                        System.arraycopy(info.abyElem, 88, temp1, 0, 4);
944
                                        psCell.origin.y = DGN_INT32(temp1);
945

    
946
                                        {
947
                                                double a;
948
                                                double b;
949
                                                double c;
950
                                                double d;
951
                                                double a2;
952
                                                double c2;
953
                                                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
954
                                                a = DGN_INT32(temp1);
955
                                                System.arraycopy(info.abyElem, 72, temp1, 0, 4);
956
                                                b = DGN_INT32(temp1);
957
                                                System.arraycopy(info.abyElem, 76, temp1, 0, 4);
958
                                                c = DGN_INT32(temp1);
959
                                                System.arraycopy(info.abyElem, 80, temp1, 0, 4);
960
                                                d = DGN_INT32(temp1);
961
                                                a2 = a * a;
962
                                                c2 = c * c;
963
                                                psCell.xscale = Math.sqrt(a2 + c2) / 214748;
964
                                                psCell.yscale = Math.sqrt((b * b) + (d * d)) / 214748;
965
                                                psCell.rotation = Math.acos(a / Math.sqrt(a2 + c2));
966

    
967
                                                if (b <= 0) {
968
                                                        psCell.rotation = (psCell.rotation * 180) / Math.PI;
969
                                                } else {
970
                                                        psCell.rotation = 360 -
971
                                                                ((psCell.rotation * 180) / Math.PI);
972
                                                }
973
                                        }
974
                                } else {
975
                                        byte[] temp1 = new byte[4];
976
                                        System.arraycopy(info.abyElem, 52, temp1, 0, 4);
977
                                        psCell.rnglow.x = DGN_INT32(temp1);
978
                                        System.arraycopy(info.abyElem, 56, temp1, 0, 4);
979
                                        psCell.rnglow.y = DGN_INT32(temp1);
980
                                        System.arraycopy(info.abyElem, 60, temp1, 0, 4);
981
                                        psCell.rnglow.z = DGN_INT32(temp1);
982
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 4);
983
                                        psCell.rnghigh.x = DGN_INT32(temp1);
984
                                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
985
                                        psCell.rnghigh.y = DGN_INT32(temp1);
986
                                        System.arraycopy(info.abyElem, 72, temp1, 0, 4);
987
                                        psCell.rnghigh.z = DGN_INT32(temp1);
988

    
989
                                        System.arraycopy(info.abyElem, 112, temp1, 0, 4);
990
                                        psCell.origin.x = DGN_INT32(temp1);
991
                                        System.arraycopy(info.abyElem, 116, temp1, 0, 4);
992
                                        psCell.origin.y = DGN_INT32(temp1);
993
                                        System.arraycopy(info.abyElem, 120, temp1, 0, 4);
994
                                        psCell.origin.z = DGN_INT32(temp1);
995
                                }
996

    
997
                                DGNTransformPoint(info, psCell.rnglow);
998
                                DGNTransformPoint(info, psCell.rnghigh);
999
                                DGNTransformPoint(info, psCell.origin);
1000
                                elemento = psCell;
1001

    
1002
                                // DGNDumpElement(info,elemento,"");
1003
                        }
1004

    
1005
                        break;
1006

    
1007
                        case DGNFileHeader.DGNT_CELL_LIBRARY: {
1008
                                System.err.println("DGNT_CELL_LIBRARY");
1009

    
1010
                                DGNElemCellLibrary psCell = new DGNElemCellLibrary();
1011
                                int iWord;
1012
                                psCell.stype = DGNFileHeader.DGNST_CELL_LIBRARY;
1013
                                DGNParseCore(info, psCell);
1014

    
1015
                                byte[] temp = new byte[psCell.name.length];
1016
                                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
1017
                                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[32]) +
1018
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[33]) * 256), temp);
1019
                                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length);
1020
                                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[34]) +
1021
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[35]) * 256), temp);
1022
                                psCell.properties = info.abyElem[38] +
1023
                                        (info.abyElem[39] * 256);
1024
                                psCell.dispsymb = ByteUtils.byteToUnsignedInt(info.abyElem[40]) +
1025
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256);
1026
                                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42]) +
1027
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
1028
                                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44]) +
1029
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
1030
                                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46]) +
1031
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
1032
                                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48]) +
1033
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
1034
                                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50]) +
1035
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
1036
                                psCell.numwords = ByteUtils.byteToUnsignedInt(info.abyElem[36]) +
1037
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
1038

    
1039
                                for (iWord = 0; iWord < 9; iWord++) {
1040
                                        int iOffset = 52 + (iWord * 2);
1041
                                        System.arraycopy(psCell.name, iWord * 3, temp, 0,
1042
                                                psCell.description.length);
1043
                                        DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(
1044
                                                        info.abyElem[iOffset]) +
1045
                                                (ByteUtils.byteToUnsignedInt(info.abyElem[iOffset + 1]) * 256),
1046
                                                temp);
1047
                                }
1048

    
1049
                                elemento = psCell;
1050
                        }
1051

    
1052
                        break;
1053

    
1054
                        case DGNFileHeader.DGNT_LINE: {
1055
                                DGNElemMultiPoint psLine = new DGNElemMultiPoint();
1056
                                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
1057
                                DGNParseCore(info, psLine);
1058
                                psLine.num_vertices = 2;
1059
                                psLine.vertices = new DGNPoint[psLine.num_vertices];
1060

    
1061
                                if (info.dimension == 2) {
1062
                                        byte[] temp1 = new byte[4];
1063
                                        System.arraycopy(info.abyElem, 36, temp1, 0, 4);
1064
                                        psLine.vertices[0] = new DGNPoint();
1065
                                        psLine.vertices[0].x = DGN_INT32(temp1);
1066
                                        System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1067
                                        psLine.vertices[0].y = DGN_INT32(temp1);
1068
                                        System.arraycopy(info.abyElem, 44, temp1, 0, 4);
1069
                                        psLine.vertices[1] = new DGNPoint();
1070
                                        psLine.vertices[1].x = DGN_INT32(temp1);
1071
                                        System.arraycopy(info.abyElem, 48, temp1, 0, 4);
1072
                                        psLine.vertices[1].y = DGN_INT32(temp1);
1073
                                } else {
1074
                                        byte[] temp1 = new byte[4];
1075
                                        System.arraycopy(info.abyElem, 36, temp1, 0, 4);
1076
                                        psLine.vertices[0] = new DGNPoint();
1077
                                        psLine.vertices[0].x = DGN_INT32(temp1);
1078
                                        System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1079
                                        psLine.vertices[0].y = DGN_INT32(temp1);
1080
                                        System.arraycopy(info.abyElem, 44, temp1, 0, 4);
1081
                                        psLine.vertices[0].z = DGN_INT32(temp1);
1082
                                        System.arraycopy(info.abyElem, 48, temp1, 0, 4);
1083
                                        psLine.vertices[1] = new DGNPoint();
1084
                                        psLine.vertices[1].x = DGN_INT32(temp1);
1085
                                        System.arraycopy(info.abyElem, 52, temp1, 0, 4);
1086
                                        psLine.vertices[1].y = DGN_INT32(temp1);
1087
                                        System.arraycopy(info.abyElem, 56, temp1, 0, 4);
1088
                                        psLine.vertices[1].z = DGN_INT32(temp1);
1089
                                }
1090

    
1091
                                DGNTransformPoint(info, psLine.vertices[0]);
1092
                                DGNTransformPoint(info, psLine.vertices[1]);
1093
                                elemento = psLine;
1094
                        }
1095

    
1096
                        break;
1097

    
1098
                        case DGNFileHeader.DGNT_LINE_STRING:
1099
                        case DGNFileHeader.DGNT_SHAPE: // regular
1100
                        case DGNFileHeader.DGNT_CURVE: // mal
1101
                        case DGNFileHeader.DGNT_BSPLINE: // aceptable
1102
                         {
1103
                                DGNElemMultiPoint psLine = new DGNElemMultiPoint();
1104
                                int i;
1105
                                int count;
1106
                                int pntsize = info.dimension * 4;
1107

    
1108
                                count = ByteUtils.byteToUnsignedInt(info.abyElem[36]) +
1109
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
1110
                                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
1111
                                DGNParseCore(info, psLine);
1112

    
1113
                                if (info.nElemBytes < (38 + (count * pntsize))) {
1114
                                        System.err.println("Error en los vertices de multipunto");
1115
                                        count = (info.nElemBytes - 38) / pntsize;
1116

    
1117
                                        return null;
1118
                                }
1119

    
1120
                                psLine.num_vertices = count;
1121
                                psLine.vertices = new DGNPoint[psLine.num_vertices];
1122

    
1123
                                for (i = 0; i < psLine.num_vertices; i++) {
1124
                                        byte[] temp1 = new byte[4];
1125
                                        System.arraycopy(info.abyElem, 38 + (i * pntsize), temp1,
1126
                                                0, 4);
1127
                                        psLine.vertices[i] = new DGNPoint();
1128
                                        psLine.vertices[i].x = DGN_INT32(temp1);
1129
                                        System.arraycopy(info.abyElem, 42 + (i * pntsize), temp1,
1130
                                                0, 4);
1131
                                        psLine.vertices[i].y = DGN_INT32(temp1);
1132

    
1133
                                        if (info.dimension == 3) {
1134
                                                System.arraycopy(info.abyElem, 46 + (i * pntsize),
1135
                                                        temp1, 0, 4);
1136
                                                psLine.vertices[i].z = DGN_INT32(temp1);
1137
                                        }
1138

    
1139
                                        DGNTransformPoint(info, psLine.vertices[i]);
1140
                                }
1141

    
1142
                                elemento = psLine;
1143
                        }
1144

    
1145
                        break;
1146

    
1147
                        case DGNFileHeader.DGNT_GROUP_DATA:
1148

    
1149
                                if (nLevel == DGNFileHeader.DGN_GDL_COLOR_TABLE) {
1150
                                        elemento = DGNParseColorTable(info);
1151
                                } else {
1152
                                        elemento.stype = DGNFileHeader.DGNST_CORE;
1153
                                        DGNParseCore(info, elemento);
1154
                                }
1155

    
1156
                                // System.err.println("DGNT_GROUP_DATA (nType = 5)");
1157
                                // DGNDumpElement(info, elemento,"");
1158
                                break;
1159

    
1160
                        case DGNFileHeader.DGNT_ELLIPSE: {
1161
                                DGNElemArc psEllipse = new DGNElemArc();
1162

    
1163
                                psEllipse.stype = DGNFileHeader.DGNST_ARC;
1164
                                DGNParseCore(info, psEllipse);
1165

    
1166
                                int[] fin = new int[1];
1167
                                fin[0] = 0;
1168

    
1169
                                byte[] temp1 = new byte[8];
1170
                                System.arraycopy(info.abyElem, 36, temp1, 0, 8);
1171

    
1172
                                fin[0] = 0;
1173
                                psEllipse.primary_axis = DGNParseIEEE(temp1);
1174

    
1175
                                psEllipse.primary_axis *= info.scale;
1176
                                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
1177
                                fin[0] = 0;
1178

    
1179
                                psEllipse.secondary_axis = DGNParseIEEE(temp1);
1180
                                psEllipse.secondary_axis *= info.scale;
1181

    
1182
                                if (info.dimension == 2) {
1183
                                        System.arraycopy(info.abyElem, 52, temp1, 0, 4);
1184
                                        psEllipse.rotation = DGN_INT32(temp1);
1185
                                        psEllipse.rotation = psEllipse.rotation / 360000.0;
1186
                                        System.arraycopy(info.abyElem, 56, temp1, 0, 8);
1187
                                        fin[0] = 0;
1188

    
1189
                                        psEllipse.origin.x = DGNParseIEEE(temp1);
1190
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 8);
1191
                                        fin[0] = 0;
1192

    
1193
                                        psEllipse.origin.y = DGNParseIEEE(temp1);
1194
                                } else {
1195
                                        // leave quaternion for later 
1196
                                        System.arraycopy(info.abyElem, 68, temp1, 0, 8);
1197
                                        fin[0] = 0;
1198
                                        psEllipse.origin.x = DGNParseIEEE(temp1);
1199

    
1200
                                        System.arraycopy(info.abyElem, 76, temp1, 0, 8);
1201
                                        fin[0] = 0;
1202
                                        psEllipse.origin.y = DGNParseIEEE(temp1);
1203

    
1204
                                        System.arraycopy(info.abyElem, 84, temp1, 0, 8);
1205
                                        fin[0] = 0;
1206
                                        psEllipse.origin.z = DGNParseIEEE(temp1);
1207

    
1208
                                        System.arraycopy(info.abyElem, 52, temp1, 0, 4);
1209
                                        psEllipse.quat[0] = DGN_INT32(temp1);
1210
                                        System.arraycopy(info.abyElem, 56, temp1, 0, 4);
1211
                                        psEllipse.quat[1] = DGN_INT32(temp1);
1212
                                        System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1213
                                        psEllipse.quat[2] = DGN_INT32(temp1);
1214
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 4);
1215
                                        psEllipse.quat[3] = DGN_INT32(temp1);
1216
                                }
1217

    
1218
                                // System.err.println("Punto antes de transformar:" + psEllipse.origin.x + " " + psEllipse.origin.y);
1219
                                DGNTransformPoint(info, (psEllipse.origin));
1220

    
1221
                                // System.err.println("Punto DESPUES de transformar:" + psEllipse.origin.x + " " + psEllipse.origin.y);
1222
                                psEllipse.startang = 0.0;
1223
                                psEllipse.sweepang = 360.0;
1224
                                elemento = psEllipse;
1225

    
1226
                                // DGNDumpElement(info, elemento,"");
1227
                        }
1228

    
1229
                        break;
1230

    
1231
                        case DGNFileHeader.DGNT_ARC: {
1232
                                DGNElemArc psEllipse = new DGNElemArc();
1233
                                double nSweepVal;
1234

    
1235
                                psEllipse.stype = DGNFileHeader.DGNST_ARC;
1236
                                DGNParseCore(info, psEllipse);
1237

    
1238
                                int[] fin = new int[1];
1239
                                fin[0] = 0;
1240

    
1241
                                byte[] temp1 = new byte[8];
1242
                                System.arraycopy(info.abyElem, 36, temp1, 0, 4);
1243
                                psEllipse.startang = DGN_INT32(temp1);
1244
                                psEllipse.startang = psEllipse.startang / 360000.0;
1245

    
1246
                                /* if ((info.abyElem[41] & (byte) 0x80) != FALSE) {
1247
                                   info.abyElem[41] &= (byte) 0x7f;
1248
                                   System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1249
                                   nSweepVal = -1 * DGN_INT32(temp1);
1250
                                   } else {
1251
                                       System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1252
                                   }
1253
                                   nSweepVal = DGN_INT32(temp1); */
1254
                                if ((info.abyElem[41] & (byte) 0x80) != FALSE) {
1255
                                        info.abyElem[41] &= (byte) 0x7f;
1256
                                        System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1257
                                        nSweepVal = -1 * DGN_INT32(temp1);
1258
                                } else {
1259
                                        System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1260
                                        nSweepVal = DGN_INT32(temp1);
1261
                                }
1262

    
1263
                                if (nSweepVal == 0) {
1264
                                        psEllipse.sweepang = 360.0;
1265
                                } else {
1266
                                        psEllipse.sweepang = nSweepVal / 360000.0;
1267
                                }
1268

    
1269
                                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
1270
                                fin[0] = 0;
1271
                                psEllipse.primary_axis = DGNParseIEEE(temp1);
1272

    
1273
                                psEllipse.primary_axis *= info.scale;
1274
                                System.arraycopy(info.abyElem, 52, temp1, 0, 8);
1275
                                fin[0] = 0;
1276
                                psEllipse.secondary_axis = DGNParseIEEE(temp1);
1277

    
1278
                                psEllipse.secondary_axis *= info.scale;
1279

    
1280
                                if (info.dimension == 2) {
1281
                                        System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1282
                                        psEllipse.rotation = DGN_INT32(temp1);
1283
                                        psEllipse.rotation = psEllipse.rotation / 360000.0;
1284
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 8);
1285
                                        fin[0] = 0;
1286
                                        psEllipse.origin.x = DGNParseIEEE(temp1);
1287

    
1288
                                        System.arraycopy(info.abyElem, 72, temp1, 0, 8);
1289
                                        fin[0] = 0;
1290
                                        psEllipse.origin.y = DGNParseIEEE(temp1);
1291
                                } else {
1292
                                        // for now we don't try to handle quaternion 
1293
                                        psEllipse.rotation = 0;
1294
                                        System.arraycopy(info.abyElem, 76, temp1, 0, 8);
1295
                                        fin[0] = 0;
1296

    
1297
                                        psEllipse.origin.x = DGNParseIEEE(temp1);
1298
                                        System.arraycopy(info.abyElem, 84, temp1, 0, 8);
1299
                                        fin[0] = 0;
1300

    
1301
                                        psEllipse.origin.y = DGNParseIEEE(temp1);
1302
                                        System.arraycopy(info.abyElem, 92, temp1, 0, 8);
1303
                                        fin[0] = 0;
1304

    
1305
                                        psEllipse.origin.z = DGNParseIEEE(temp1);
1306
                                        System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1307
                                        psEllipse.quat[0] = DGN_INT32(temp1);
1308
                                        System.arraycopy(info.abyElem, 64, temp1, 0, 4);
1309
                                        psEllipse.quat[1] = DGN_INT32(temp1);
1310
                                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1311
                                        psEllipse.quat[2] = DGN_INT32(temp1);
1312
                                        System.arraycopy(info.abyElem, 72, temp1, 0, 4);
1313
                                        psEllipse.quat[3] = DGN_INT32(temp1);
1314
                                }
1315

    
1316
                                DGNTransformPoint(info, (psEllipse.origin));
1317
                                elemento = psEllipse;
1318
                        }
1319

    
1320
                        break;
1321

    
1322
                        case DGNFileHeader.DGNT_TEXT: {
1323
                                DGNElemText psText = new DGNElemText();
1324
                                int num_chars;
1325
                                int text_off;
1326

    
1327
                                if (info.dimension == 2) {
1328
                                        num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[58]);
1329
                                } else {
1330
                                        num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[74]);
1331
                                }
1332

    
1333
                                psText.stype = DGNFileHeader.DGNST_TEXT;
1334
                                DGNParseCore(info, psText);
1335

    
1336
                                psText.font_id = ByteUtils.byteToUnsignedInt(info.abyElem[36]);
1337
                                psText.justification = ByteUtils.byteToUnsignedInt(info.abyElem[37]);
1338

    
1339
                                byte[] temp1 = new byte[8];
1340
                                System.arraycopy(info.abyElem, 38, temp1, 0, 4);
1341
                                psText.length_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
1342
                                System.arraycopy(info.abyElem, 42, temp1, 0, 4);
1343
                                psText.height_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
1344

    
1345
                                int[] fin = new int[1];
1346
                                fin[0] = 0;
1347

    
1348
                                if (info.dimension == 2) {
1349
                                        System.arraycopy(info.abyElem, 46, temp1, 0, 4);
1350
                                        psText.rotation = DGN_INT32(temp1);
1351
                                        psText.rotation = psText.rotation / 360000.0;
1352
                                        System.arraycopy(info.abyElem, 50, temp1, 0, 4);
1353
                                        psText.origin.x = DGN_INT32(temp1);
1354
                                        System.arraycopy(info.abyElem, 54, temp1, 0, 4);
1355
                                        psText.origin.y = DGN_INT32(temp1);
1356
                                        text_off = 60;
1357
                                } else {
1358
                                        /* leave quaternion for later */
1359
                                        System.arraycopy(info.abyElem, 62, temp1, 0, 4);
1360
                                        psText.origin.x = DGN_INT32(temp1);
1361
                                        System.arraycopy(info.abyElem, 66, temp1, 0, 4);
1362
                                        psText.origin.y = DGN_INT32(temp1);
1363
                                        System.arraycopy(info.abyElem, 70, temp1, 0, 4);
1364
                                        psText.origin.z = DGN_INT32(temp1);
1365
                                        text_off = 76;
1366
                                }
1367

    
1368
                                // System.err.println("Punto antes de transformar:" + psText.origin.x + " " + psText.origin.y);
1369
                                DGNTransformPoint(info, (psText.origin));
1370

    
1371
                                // AQUI FALTA METER ALGO PARA SOPORTAR TEXTOS MULTYBYTE
1372
                                byte[] temp = new byte[num_chars];
1373
                                System.arraycopy(info.abyElem, text_off, temp, 0, num_chars);
1374

    
1375
                                // fin[0] = 0;
1376
                                String strAux = null;
1377

    
1378
                                try {
1379
                                        psText.string = new String(temp, "ISO-8859-1");
1380

    
1381
                                        // System.err.println(strAux);
1382
                                } catch (Exception e) {
1383
                                        e.printStackTrace();
1384
                                }
1385

    
1386
                                elemento = psText;
1387
                        }
1388

    
1389
                        break;
1390

    
1391
                        case DGNFileHeader.DGNT_TCB:
1392
                                elemento = DGNParseTCB(info);
1393
                                elemento.level = nLevel;
1394
                                elemento.type = nType;
1395

    
1396
                                break;
1397

    
1398
                        case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
1399
                        case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER: {
1400
                                DGNElemComplexHeader psHdr = new DGNElemComplexHeader();
1401

    
1402
                                psHdr.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
1403
                                DGNParseCore(info, psHdr);
1404

    
1405
                                psHdr.totlength = ByteUtils.byteToUnsignedInt(info.abyElem[36]) +
1406
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
1407
                                psHdr.numelems = ByteUtils.byteToUnsignedInt(info.abyElem[38]) +
1408
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256);
1409
                                elemento = psHdr;
1410
                        }
1411

    
1412
                        break;
1413

    
1414
                        case DGNFileHeader.DGNT_TAG_VALUE: {
1415
                                DGNElemTagValue psTag = new DGNElemTagValue();
1416

    
1417
                                psTag.stype = DGNFileHeader.DGNST_TAG_VALUE;
1418
                                DGNParseCore(info, psTag);
1419

    
1420
                                int[] fin = new int[1];
1421
                                fin[0] = 0;
1422

    
1423
                                byte[] temp1 = new byte[8];
1424
                                psTag.tagType = ByteUtils.byteToUnsignedInt(info.abyElem[74]) +
1425
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[75]) * 256);
1426
                                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1427
                                fin[0] = 0;
1428
                                psTag.tagSet = ByteUtils.bytesToInt(temp1, fin);
1429

    
1430
                                psTag.tagSet = CPL_LSBWORD32(psTag.tagSet);
1431
                                psTag.tagIndex = ByteUtils.byteToUnsignedInt(info.abyElem[72]) +
1432
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[73]) * 256);
1433
                                psTag.tagLength = ByteUtils.byteToUnsignedInt(info.abyElem[150]) +
1434
                                        (ByteUtils.byteToUnsignedInt(info.abyElem[151]) * 256);
1435

    
1436
                                if (psTag.tagType == 1) {
1437
                                        byte[] temp = new byte[info.abyElem.length - 154];
1438
                                        System.arraycopy(info.abyElem, 4, temp1, 0, //154
1439
                                                4); //info.abyElem.length - 154
1440
                                        fin[0] = 0;
1441
                                        psTag.tagValue.string = CPLStrdup(ByteUtils.bytesToString(
1442
                                                                temp1, fin).toCharArray());
1443
                                } else if (psTag.tagType == 3) {
1444
                                        byte[] temp = new byte[4];
1445
                                        System.arraycopy(info.abyElem, 154, temp1, 0, 4);
1446
                                        fin[0] = 0;
1447
                                        psTag.tagValue.integer = ByteUtils.bytesToInt(temp1, fin);
1448

    
1449
                                        psTag.tagValue.integer = CPL_LSBWORD32((int) psTag.tagValue.integer);
1450
                                } else if (psTag.tagType == 4) {
1451
                                        byte[] temp = new byte[8];
1452
                                        System.arraycopy(info.abyElem, 154, temp1, 0, 8);
1453
                                        fin[0] = 0;
1454
                                        psTag.tagValue.real = DGNParseIEEE(temp1);
1455
                                }
1456

    
1457
                                elemento = psTag;
1458
                        }
1459

    
1460
                        break;
1461

    
1462
                        /* case DGNFileHeader.DGNT_APPLICATION_ELEM:
1463
                           if (nLevel == 24) {
1464
                               elemento = DGNParseTagSet(info);
1465
                           } else {
1466
                               elemento.stype = DGNFileHeader.DGNST_CORE;
1467
                               DGNParseCore(info, elemento);
1468
                           }
1469
                           break; */
1470
                        default: {
1471
                                // System.err.println("Entra un " + nType + " en DGNProcessElement");
1472
                                elemento.stype = DGNFileHeader.DGNST_CORE;
1473
                                DGNParseCore(info, elemento);
1474
                        }
1475

    
1476
                        break;
1477
                }
1478

    
1479
                /* -------------------------------------------------------------------- */
1480
                /*      If the element structure type is "core" or if we are running    */
1481
                /*      in "capture all" mode, record the complete binary image of      */
1482
                /*      the element.                                                    */
1483
                /* -------------------------------------------------------------------- */
1484
                if ((elemento.stype == DGNFileHeader.DGNST_CORE) ||
1485
                                ((info.options & DGNFileHeader.DGNO_CAPTURE_RAW_DATA) != FALSE)) {
1486
                        elemento.raw_bytes = info.nElemBytes;
1487

    
1488
                        elemento.raw_data = new byte[elemento.raw_bytes];
1489

    
1490
                        int[] fin = new int[1];
1491
                        fin[0] = 0;
1492
                        System.arraycopy(info.abyElem, 0, elemento.raw_data, 0,
1493
                                elemento.raw_bytes);
1494
                }
1495

    
1496
                /* -------------------------------------------------------------------- */
1497
                /*      Collect some additional generic information.                    */
1498
                /* -------------------------------------------------------------------- */
1499
                elemento.element_id = info.next_element_id - 1;
1500

    
1501
                elemento.offset = info.ftall - info.nElemBytes;
1502
                elemento.size = info.nElemBytes;
1503

    
1504
                // DGNDumpElement(info, elemento,"");
1505
                return elemento;
1506
        }
1507

    
1508
        /**
1509
         * DOCUMENT ME!
1510
         *
1511
         * @param d DOCUMENT ME!
1512
         *
1513
         * @return DOCUMENT ME!
1514
         */
1515
        private double DGNParseIEEE(double d) {
1516
                byte[] temp = new byte[8];
1517
                int[] f = { 0 };
1518
                ByteUtils.doubleToBytes(d, temp, f);
1519

    
1520
                return DGNParseIEEE(temp);
1521
        }
1522

    
1523
        /**
1524
         * DOCUMENT ME!
1525
         *
1526
         * @param b DOCUMENT ME!
1527
         *
1528
         * @return DOCUMENT ME!
1529
         */
1530
        private double DGNParseIEEE(byte[] b) {
1531
                byte BYTE2 = b[7];
1532
                byte BYTE3 = b[6];
1533
                byte BYTE0 = b[5];
1534
                byte BYTE1 = b[4];
1535
                byte BYTE6 = b[3];
1536
                byte BYTE7 = b[2];
1537
                byte BYTE4 = b[1];
1538
                byte BYTE5 = b[0];
1539
                int sign;
1540
                int exponent;
1541
                int fraction;
1542
                double value;
1543
                int hi;
1544
                int lo;
1545
                int rndbits;
1546

    
1547
                /* -------------------------------------------------------------------- */
1548
                /*        Save the sign of the double                                        */
1549
                /* -------------------------------------------------------------------- */
1550
                byte[] temp = new byte[4];
1551
                byte[] temp1 = new byte[4];
1552

    
1553
                temp[3] = BYTE7;
1554
                temp[2] = BYTE6;
1555
                temp[1] = BYTE5;
1556
                temp[0] = BYTE4;
1557

    
1558
                int[] f = { 0 };
1559
                hi = ByteUtils.bytesToInt(temp, f);
1560
                sign = hi & 0x80000000;
1561

    
1562
                /* -------------------------------------------------------------------- */
1563
                /*        Adjust the exponent so that we may work with it                        */
1564
                /* -------------------------------------------------------------------- */
1565
                exponent = hi >> 23;
1566
                exponent = exponent & 0x000000ff;
1567

    
1568
                if (exponent != 0) {
1569
                        exponent = exponent - 129 + 1023;
1570
                }
1571

    
1572
                /* -------------------------------------------------------------------- */
1573
                /*        Save the bits that we are discarding so we can round properly        */
1574
                /* -------------------------------------------------------------------- */
1575
                temp[3] = BYTE3;
1576
                temp[2] = BYTE2;
1577
                temp[1] = BYTE1;
1578
                temp[0] = BYTE0;
1579

    
1580
                f[0] = 0;
1581
                lo = ByteUtils.bytesToInt(temp, f);
1582
                rndbits = lo & 0x00000007;
1583

    
1584
                lo = lo >> 3;
1585
                lo = (lo & 0x1fffffff) | (hi << 29);
1586

    
1587
                if (rndbits != 0) {
1588
                        lo = lo | 0x00000001;
1589
                }
1590

    
1591
                /* -------------------------------------------------------------------- */
1592
                /*        Shift the hi-order int over 3 and insert the exponent and sign        */
1593
                /* -------------------------------------------------------------------- */
1594
                hi = hi >> 3;
1595
                hi = hi & 0x000fffff;
1596
                hi = hi | (exponent << 20) | sign;
1597
                f[0] = 0;
1598
                ByteUtils.intToBytes(hi, temp, f);
1599
                f[0] = 0;
1600
                ByteUtils.intToBytes(lo, temp1, f);
1601

    
1602
                byte[] result = new byte[8];
1603
                result[7] = temp1[3];
1604
                result[6] = temp1[2];
1605
                result[5] = temp1[1];
1606
                result[4] = temp1[0];
1607
                result[3] = temp[3];
1608
                result[2] = temp[2];
1609
                result[1] = temp[1];
1610
                result[0] = temp[0];
1611

    
1612
                f[0] = 0;
1613

    
1614
                value = ByteUtils.bytesToDouble(result, f);
1615

    
1616
                return value;
1617
        }
1618

    
1619
        /**
1620
         * Cambia el double a IEEDouble.
1621
         *
1622
         * @param dbl double de entrada.
1623
         */
1624
        private void DGN2IEEEDouble(double dbl) {
1625
                double64 dt = new double64();
1626

    
1627
                dt.hi = 0;
1628
                dt.lo = 0;
1629

    
1630
                long sign = 0;
1631
                long exponent = 0;
1632
                long rndbits;
1633
                byte[] srclo = new byte[4];
1634
                byte[] srchi = new byte[4];
1635
                byte[] destlo = new byte[4];
1636
                byte[] desthi = new byte[4];
1637
                byte[] src = new byte[8];
1638
                byte[] dest = new byte[8];
1639

    
1640
                for (int i = 0; i < 8; i++) {
1641
                        src[i] = 0;
1642
                        dest[i] = 0;
1643
                }
1644

    
1645
                int[] fin = new int[1];
1646

    
1647
                fin[0] = 0;
1648
                ByteUtils.doubleToBytes(dbl, src, fin);
1649

    
1650
                if (LSB == TRUE) {
1651
                        dest[2] = src[0];
1652
                        dest[3] = src[1];
1653
                        dest[0] = src[2];
1654
                        dest[1] = src[3];
1655
                        dest[6] = src[4];
1656
                        dest[7] = src[5];
1657
                        dest[4] = src[6];
1658
                        dest[5] = src[7];
1659
                } else {
1660
                        dest[1] = src[0];
1661
                        dest[0] = src[1];
1662
                        dest[3] = src[2];
1663
                        dest[2] = src[3];
1664
                        dest[5] = src[4];
1665
                        dest[4] = src[5];
1666
                        dest[7] = src[6];
1667
                        dest[6] = src[7];
1668
                }
1669

    
1670
                System.arraycopy(dest, 0, destlo, 0, 4);
1671
                fin[0] = 0;
1672
                dt.lo = ByteUtils.bytesToLong(destlo, fin);
1673
                System.arraycopy(dest, 4, desthi, 0, 4);
1674
                fin[0] = 0;
1675
                dt.hi = ByteUtils.bytesToLong(desthi, fin);
1676
                sign = dt.hi & 0x80000000;
1677
                exponent = dt.hi >> 23;
1678
                exponent = (long) exponent & 0x000000ff;
1679

    
1680
                if (exponent != FALSE) {
1681
                        exponent = exponent - 129 + 1023;
1682
                }
1683

    
1684
                rndbits = dt.lo & 0x00000007;
1685
                dt.lo = dt.lo >> 3;
1686
                dt.lo = (dt.lo & 0x1fffffff) | (dt.hi << 29);
1687

    
1688
                if (rndbits != FALSE) {
1689
                        dt.lo = dt.lo | 0x00000001;
1690
                }
1691

    
1692
                dt.hi = dt.hi >> 3;
1693
                dt.hi = dt.hi & 0x000fffff;
1694
                dt.hi = dt.hi | ((long) exponent << 20) | (long) sign;
1695

    
1696
                if (LSB == TRUE) {
1697
                        fin[0] = 0;
1698
                        ByteUtils.longToBytes(dt.lo, srclo, fin);
1699
                        fin[0] = 0;
1700
                        ByteUtils.longToBytes(dt.hi, srchi, fin);
1701
                        dest[0] = srchi[0];
1702
                        dest[1] = srchi[1];
1703
                        dest[2] = srchi[2];
1704
                        dest[3] = srchi[3];
1705
                        dest[4] = srclo[0];
1706
                        dest[5] = srclo[1];
1707
                        dest[6] = srclo[2];
1708
                        dest[7] = srclo[3];
1709
                } else {
1710
                        //memcpy( dbl, &dt, 8 );
1711
                }
1712
        }
1713

    
1714
        /**
1715
         * DOCUMENT ME!
1716
         *
1717
         * @param dbl DOCUMENT ME!
1718
         */
1719
        private void IEEE2DGNDouble(double dbl) {
1720
                double64 dt = new double64();
1721

    
1722
                dt.hi = 0;
1723
                dt.lo = 0;
1724

    
1725
                long sign;
1726
                long exponent;
1727
                long rndbits;
1728
                byte[] srclo = new byte[4];
1729
                byte[] srchi = new byte[4];
1730
                byte[] destlo = new byte[4];
1731
                byte[] desthi = new byte[4];
1732
                byte[] src = new byte[8];
1733
                byte[] dest = new byte[8];
1734

    
1735
                for (int i = 0; i < 8; i++) {
1736
                        src[i] = '0';
1737
                        dest[i] = '0';
1738
                }
1739

    
1740
                int[] fin = new int[1];
1741

    
1742
                if (LSB == TRUE) {
1743
                        fin[0] = 0;
1744
                        ByteUtils.doubleToBytes(dbl, src, fin);
1745
                        dest[0] = src[4];
1746
                        dest[1] = src[5];
1747
                        dest[2] = src[6];
1748
                        dest[3] = src[7];
1749
                        dest[4] = src[0];
1750
                        dest[5] = src[1];
1751
                        dest[6] = src[2];
1752
                        dest[7] = src[3];
1753
                } else {
1754
                        //memcpy( &dt, dbl, 8 );
1755
                }
1756

    
1757
                sign = dt.hi & 0x80000000;
1758
                exponent = dt.hi >> 20;
1759
                exponent = exponent & 0x000007ff;
1760

    
1761
                /* -------------------------------------------------------------------- */
1762
                /*        An exponent of zero means a zero value.                                */
1763
                /* -------------------------------------------------------------------- */
1764
                if (exponent != FALSE) {
1765
                        exponent = exponent - 1023 + 129;
1766
                }
1767

    
1768
                /* -------------------------------------------------------------------- */
1769
                /*        In the case of overflow, return the largest number we can        */
1770
                /* -------------------------------------------------------------------- */
1771
                if (exponent > 255) {
1772
                        fin[0] = 0;
1773
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1774

    
1775
                        if (sign != FALSE) {
1776
                                dest[1] = 0xf;
1777
                        } else {
1778
                                dest[1] = 0x7f;
1779
                        }
1780

    
1781
                        dest[0] = 0xf;
1782
                        dest[2] = 0xf;
1783
                        dest[3] = 0xf;
1784
                        dest[4] = 0xf;
1785
                        dest[5] = 0xf;
1786
                        dest[6] = 0xf;
1787
                        dest[7] = 0xf;
1788

    
1789
                        return;
1790
                }
1791
                /* -------------------------------------------------------------------- */
1792
                /*        In the case of of underflow return zero                                */
1793
                /* -------------------------------------------------------------------- */
1794
                else if ((exponent < 0) || ((exponent == 0) && (sign == 0))) {
1795
                        fin[0] = 0;
1796
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1797
                        dest[0] = 0x00;
1798
                        dest[1] = 0x00;
1799
                        dest[2] = 0x00;
1800
                        dest[3] = 0x00;
1801
                        dest[4] = 0x00;
1802
                        dest[5] = 0x00;
1803
                        dest[6] = 0x00;
1804
                        dest[7] = 0x00;
1805

    
1806
                        return;
1807
                } else {
1808
                        /* -------------------------------------------------------------------- */
1809
                        /*            Shift the fraction 3 bits left and set the exponent and sign*/
1810
                        /* -------------------------------------------------------------------- */
1811
                        System.arraycopy(dest, 0, destlo, 0, 4);
1812
                        fin[0] = 0;
1813
                        dt.lo = ByteUtils.bytesToLong(destlo, fin);
1814
                        System.arraycopy(dest, 4, desthi, 0, 4);
1815
                        fin[0] = 0;
1816
                        dt.hi = ByteUtils.bytesToLong(desthi, fin);
1817

    
1818
                        dt.hi = dt.hi << 3;
1819
                        dt.hi = dt.hi | (dt.lo >> 29);
1820
                        dt.hi = dt.hi & 0x007fffff;
1821
                        dt.hi = dt.hi | (exponent << 23) | sign;
1822

    
1823
                        dt.lo = dt.lo << 3;
1824
                }
1825

    
1826
                /* -------------------------------------------------------------------- */
1827
                /*        Convert the double back to VAX format                                */
1828
                /* -------------------------------------------------------------------- */
1829
                fin[0] = 0;
1830

    
1831
                ByteUtils.longToBytes(dt.lo, srclo, fin);
1832

    
1833
                fin[0] = 0;
1834
                ByteUtils.longToBytes(dt.hi, srchi, fin);
1835

    
1836
                if (LSB == TRUE) {
1837
                        dest[2] = srclo[0];
1838
                        dest[3] = srclo[1];
1839
                        dest[0] = srclo[2];
1840
                        dest[1] = srclo[3];
1841
                        dest[6] = srchi[0];
1842
                        dest[7] = srchi[1];
1843
                        dest[4] = srchi[2];
1844
                        dest[5] = srchi[3];
1845
                } else {
1846
                        dest[1] = srclo[0];
1847
                        dest[0] = srclo[1];
1848
                        dest[3] = srclo[2];
1849
                        dest[2] = srclo[3];
1850
                        dest[5] = srchi[0];
1851
                        dest[4] = srchi[1];
1852
                        dest[7] = srchi[2];
1853
                        dest[6] = srchi[3];
1854
                }
1855

    
1856
                fin[0] = 0;
1857
                dbl = ByteUtils.bytesToDouble(dest, fin);
1858

    
1859
                ////System.out.println("dbl=  " + dbl);
1860
        }
1861

    
1862
        /************************************************************************/
1863
        /*                       DGNElemTypeHasDispHdr()                        */
1864
        /************************************************************************/
1865

    
1866
        /**
1867
         * Does element type have display header.
1868
         *
1869
         * @param nElemType element type (0-63) to test.
1870
         *
1871
         * @return TRUE if elements of passed in type have a display header after
1872
         *                    the core element header, or FALSE otherwise.
1873
         */
1874
        private int DGNElemTypeHasDispHdr(int nElemType) {
1875
                switch (nElemType) {
1876
                        case 0:
1877
                        case DGNFileHeader.DGNT_TCB:
1878
                        case DGNFileHeader.DGNT_CELL_LIBRARY:
1879
                        case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
1880
                        case 32:
1881
                        case 44:
1882
                        case 48:
1883
                        case 49:
1884
                        case 50:
1885
                        case 51:
1886
                        case 57:
1887
                        case 63:
1888
                                return FALSE;
1889

    
1890
                        default:
1891
                                return TRUE;
1892
                }
1893
        }
1894

    
1895
        /**
1896
         * DOCUMENT ME!
1897
         *
1898
         * @param info DOCUMENT ME!
1899
         * @param elemento DOCUMENT ME!
1900
         *
1901
         * @return DOCUMENT ME!
1902
         */
1903
        private int DGNParseCore(DGNInfo info, DGNElemCore elemento) {
1904
                byte[] psData = info.abyElem; //0
1905

    
1906
                elemento.level = psData[0] & (byte) 0x3f;
1907
                elemento.complex = psData[0] & (byte) 0x80;
1908
                elemento.deleted = psData[1] & (byte) 0x80;
1909
                elemento.type = psData[1] & (byte) 0x7f;
1910

    
1911
                if ((info.nElemBytes >= 36) &&
1912
                                (DGNElemTypeHasDispHdr(elemento.type) == TRUE)) {
1913
                        // (elemento.type != DGNFileHeader.DGNT_CELL_LIBRARY)) {
1914
                        elemento.graphic_group = psData[28] + (psData[29] * 256);
1915
                        elemento.properties = psData[32] + (psData[33] * 256);
1916

    
1917
                        elemento.style = psData[34] & (byte) 0x7;
1918
                        elemento.weight = (psData[34] & (byte) 0xf8) >> 3;
1919

    
1920
                        byte aux = psData[35];
1921

    
1922
                        // System.out.println("aux = " + aux);
1923
                        elemento.color = ByteUtils.getUnsigned(aux);
1924

    
1925
                        // elemento.color = psData[35];
1926
                        // System.out.println("elemento.color = " + elemento.color);
1927
                } else {
1928
                        elemento.graphic_group = 0;
1929
                        elemento.properties = 0;
1930
                        elemento.style = 0;
1931
                        elemento.weight = 0;
1932
                        elemento.color = 0;
1933
                }
1934

    
1935
                if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
1936
                        // if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) == TRUE) {
1937
                        int nAttIndex;
1938

    
1939
                        nAttIndex = ByteUtils.getUnsigned(psData[30]) +
1940
                                (ByteUtils.getUnsigned(psData[31]) * 256);
1941

    
1942
                        int numBytes = info.nElemBytes - (nAttIndex * 2) - 32;
1943

    
1944
                        if ((numBytes > 0)) {
1945
                                // Como m?ximo guardamos 10 bytes (Total, lo queremos para el color....
1946
                                // if (numBytes > 10) numBytes = 10;
1947
                                elemento.attr_bytes = numBytes;
1948

    
1949
                                elemento.attr_data = new byte[elemento.attr_bytes];
1950

    
1951
                                // System.out.println("nAttIndex = " + nAttIndex + " numBytes = " + numBytes );
1952
                                System.arraycopy(psData, (nAttIndex * 2) + 32,
1953
                                        elemento.attr_data, 0, elemento.attr_bytes);
1954
                        }
1955
                }
1956

    
1957
                return TRUE;
1958
        }
1959

    
1960
        /**
1961
         * DOCUMENT ME!
1962
         *
1963
         * @param rad50 DOCUMENT ME!
1964
         * @param str DOCUMENT ME!
1965
         */
1966
        private void DGNRad50ToAscii(int rad50, byte[] str) {
1967
                byte cTimes;
1968
                int value;
1969
                int temp;
1970
                byte ch = '\0';
1971
                int i = 0;
1972

    
1973
                while (rad50 > 0) {
1974
                        value = rad50;
1975
                        cTimes = 0;
1976

    
1977
                        while (value >= 40) {
1978
                                value /= 40;
1979
                                cTimes++;
1980
                        }
1981

    
1982
                        byte[] abc = {
1983
                                        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
1984
                                        'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
1985
                                        'Y', 'Z'
1986
                                };
1987
                        byte[] num = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
1988

    
1989
                        /* Map 0..39 to ASCII */
1990
                        if (value == 0) {
1991
                                ch = ' '; /* space */
1992
                        } else if ((value >= 1) && (value <= 26)) {
1993
                                ch = abc[value - 1]; /* printable alpha A..Z */
1994
                        } else if (value == 27) {
1995
                                ch = '$'; /* dollar */
1996
                        } else if (value == 28) {
1997
                                ch = '.'; /* period */
1998
                        } else if (value == 29) {
1999
                                ch = ' '; /* unused char, emit a space instead */
2000
                        } else if ((value >= 30) && (value <= 39)) {
2001
                                ch = num[value - 30]; /* digit 0..9 */
2002
                        }
2003

    
2004
                        str[i] = ch;
2005
                        i++;
2006

    
2007
                        temp = 1;
2008

    
2009
                        while (cTimes-- > 0)
2010
                                temp *= 40;
2011

    
2012
                        rad50 -= (value * temp);
2013
                }
2014

    
2015
                /* Do zero-terminate */
2016
                str[i] = '\0';
2017
        }
2018

    
2019
        /**
2020
         * Transforma el punto.
2021
         *
2022
         * @param info Informaci?n del DGN.
2023
         * @param psPoint Punto.
2024
         */
2025
        private void DGNTransformPoint(DGNInfo info, DGNPoint psPoint) {
2026
                psPoint.x = (psPoint.x * info.scale) - info.origin_x;
2027

    
2028
                // System.out.println("info.scale= "+info.scale+"info.origin_x= "+info.origin_x);
2029
                psPoint.y = (psPoint.y * info.scale) - info.origin_y;
2030

    
2031
                // System.out.println("info.origin_y= "+info.origin_y);
2032
                psPoint.z = (psPoint.z * info.scale) - info.origin_z;
2033

    
2034
                // System.out.println("x= "+psPoint.x+"y= "+psPoint.y);
2035
        }
2036

    
2037
        /**
2038
         * DOCUMENT ME!
2039
         *
2040
         * @param psDGN DOCUMENT ME!
2041
         *
2042
         * @return DOCUMENT ME!
2043
         */
2044
        private DGNElemCore DGNParseColorTable(DGNInfo psDGN) {
2045
                DGNElemColorTable psColorTable = new DGNElemColorTable();
2046

    
2047
                psColorTable.stype = DGNFileHeader.DGNST_COLORTABLE;
2048

    
2049
                DGNParseCore(psDGN, psColorTable);
2050

    
2051
                psColorTable.screen_flag = ByteUtils.byteToUnsignedInt(psDGN.abyElem[36]) +
2052
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[37]) * 256);
2053

    
2054
                int[] fin = new int[1];
2055
                fin[0] = 0;
2056

    
2057
                byte[] temp = new byte[3];
2058
                System.arraycopy(psDGN.abyElem, 38, temp, 0, 3);
2059
                psColorTable.color_info[255] = temp;
2060

    
2061
                byte[] temp2 = new byte[765];
2062
                System.arraycopy(psDGN.abyElem, 41, temp2, 0, 765);
2063

    
2064
                int k = 0;
2065

    
2066
                for (int i = 0; i < 255; i++) {
2067
                        for (int j = 0; j < 3; j++) {
2068
                                psColorTable.color_info[i][j] = temp2[k];
2069
                                k++;
2070
                        }
2071

    
2072
                        // System.err.println("Color " + psColorTable.color_info[i][0] + " " + 
2073
                        //                psColorTable.color_info[i][1] + " " + psColorTable.color_info[i][2]);
2074
                }
2075

    
2076
                if (psDGN.got_color_table == FALSE) {
2077
                        psDGN.color_table = psColorTable.color_info;
2078

    
2079
                        psDGN.got_color_table = 1;
2080
                }
2081

    
2082
                return psColorTable;
2083
        }
2084

    
2085
        /**
2086
         * DOCUMENT ME!
2087
         *
2088
         * @param psDGN DOCUMENT ME!
2089
         *
2090
         * @return DOCUMENT ME!
2091
         */
2092
        private DGNElemCore DGNParseTCB(DGNInfo psDGN) {
2093
                DGNElemTCB psTCB = new DGNElemTCB();
2094
                int iView;
2095
                int[] fin = new int[1];
2096
                psTCB.stype = DGNFileHeader.DGNST_TCB;
2097
                DGNParseCore(psDGN, psTCB);
2098

    
2099
                if ((psDGN.abyElem[1214] & (byte) 0x40) != FALSE) {
2100
                        psTCB.dimension = 3;
2101
                } else {
2102
                        psTCB.dimension = 2;
2103
                }
2104

    
2105
                // psTCB.dimension = 3;
2106
                fin[0] = 0;
2107

    
2108
                byte[] temp1 = new byte[8];
2109
                System.arraycopy(psDGN.abyElem, 1112, temp1, 0, 4);
2110
                psTCB.subunits_per_master = DGN_INT32(temp1);
2111

    
2112
                psTCB.master_units[0] = (char) (psDGN.abyElem[1120]);
2113
                psTCB.master_units[1] = (char) (psDGN.abyElem[1121]);
2114
                psTCB.master_units[2] = '\0';
2115

    
2116
                System.arraycopy(psDGN.abyElem, 1116, temp1, 0, 4);
2117
                psTCB.uor_per_subunit = DGN_INT32(temp1);
2118

    
2119
                psTCB.sub_units[0] = (char) (psDGN.abyElem[1122]);
2120
                psTCB.sub_units[1] = (char) (psDGN.abyElem[1123]);
2121
                psTCB.sub_units[2] = '\0';
2122

    
2123
                /* Get global origin */
2124
                System.arraycopy(psDGN.abyElem, 1240, temp1, 0, 8);
2125

    
2126
                fin[0] = 0;
2127
                psTCB.origin_x = ByteUtils.bytesToDouble(temp1, fin);
2128

    
2129
                System.arraycopy(psDGN.abyElem, 1248, temp1, 0, 8);
2130
                fin[0] = 0;
2131
                psTCB.origin_y = ByteUtils.bytesToDouble(temp1, fin);
2132

    
2133
                fin[0] = 0;
2134
                System.arraycopy(psDGN.abyElem, 1256, temp1, 0, 8);
2135
                fin[0] = 0;
2136
                psTCB.origin_z = ByteUtils.bytesToDouble(temp1, fin);
2137

    
2138
                /* Transform to IEEE */
2139
                DGNParseIEEE(psTCB.origin_x);
2140
                DGNParseIEEE(psTCB.origin_y);
2141
                DGNParseIEEE(psTCB.origin_z);
2142

    
2143
                /* Convert from UORs to master units. */
2144
                if ((psTCB.uor_per_subunit != 0) && (psTCB.subunits_per_master != 0)) {
2145
                        psTCB.origin_x = psTCB.origin_x / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2146
                        psTCB.origin_y = psTCB.origin_y / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2147
                        psTCB.origin_z = psTCB.origin_z / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2148
                }
2149

    
2150
                // psDGN.dimension = psTCB.dimension;
2151
                if (psDGN.got_tcb == FALSE) {
2152
                        psDGN.got_tcb = TRUE;
2153

    
2154
                        /* psDGN.origin_x = psTCB.origin_x;
2155
                           psDGN.origin_y = psTCB.origin_y;
2156
                           psDGN.origin_z = psTCB.origin_z; */
2157
                        if ((psTCB.uor_per_subunit != 0) &&
2158
                                        (psTCB.subunits_per_master != 0)) {
2159
                                psDGN.scale = 1.0 / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2160
                        }
2161
                }
2162

    
2163
                /* System.err.println("Ojo: HAY TCB!!");
2164
                   System.out.println("Datos del TCB: " + psTCB.origin_x + " " + psTCB.origin_y);
2165
                   System.out.println("psTCB.uor_per_subunit: " + psTCB.uor_per_subunit + " psTCB.subunits_per_master: " + psTCB.subunits_per_master);
2166
                   // System.out.println("psTCB.master_units = " + new String(psTCB.master_units) +
2167
                   //                 " psTCB.sub_units = " + new String(psTCB.sub_units));
2168
                   System.out.println("psTCB.origen = " + psTCB.origin_x + " " + psTCB.origin_y);
2169
                   System.out.println("psDGN.scale = " + psDGN.scale);
2170
                   System.out.println("psDGN.origen = " + psDGN.origin_x + " " + psDGN.origin_y);
2171
                   System.out.println("psDGN.dimension = " + psDGN.dimension); */
2172
                /* Collect views */
2173
                for (iView = 0; iView < 8; iView++) {
2174
                        byte[] pabyRawView = new byte[psDGN.abyElem.length];
2175
                        fin[0] = 0;
2176
                        System.arraycopy(psDGN.abyElem, (46 + (iView * 118)), pabyRawView,
2177
                                0, psDGN.abyElem.length - (46 + (iView * 118)));
2178

    
2179
                        psTCB.views[iView] = new DGNViewInfo();
2180
                        psTCB.views[iView].flags = ByteUtils.byteToUnsignedInt(pabyRawView[0]) +
2181
                                (ByteUtils.byteToUnsignedInt(pabyRawView[1]) * 256);
2182

    
2183
                        byte[] temp2 = new byte[4];
2184
                        int f = 0;
2185

    
2186
                        for (int j = 0; j < 8; j++) {
2187
                                System.arraycopy(pabyRawView, j + 2, temp2, 0, 1);
2188
                                fin[0] = 0;
2189
                                psTCB.views[iView].levels[f] = temp2[0];
2190
                                f++;
2191
                        }
2192

    
2193
                        psTCB.views[iView].origin = new DGNPoint();
2194
                        System.arraycopy(pabyRawView, 10, temp1, 0, 4);
2195
                        psTCB.views[iView].origin.x = DGN_INT32(temp1);
2196

    
2197
                        System.arraycopy(pabyRawView, 14, temp1, 0, 4);
2198
                        psTCB.views[iView].origin.y = DGN_INT32(temp1);
2199
                        System.arraycopy(pabyRawView, 18, temp1, 0, 4);
2200
                        psTCB.views[iView].origin.z = DGN_INT32(temp1);
2201
                        DGNTransformPoint(psDGN, (psTCB.views[iView].origin));
2202

    
2203
                        psTCB.views[iView].delta = new DGNPoint();
2204
                        System.arraycopy(pabyRawView, 22, temp1, 0, 4);
2205
                        psTCB.views[iView].delta.x = DGN_INT32(temp1);
2206
                        System.arraycopy(pabyRawView, 26, temp1, 0, 4);
2207
                        psTCB.views[iView].delta.y = DGN_INT32(temp1);
2208
                        System.arraycopy(pabyRawView, 30, temp1, 0, 4);
2209
                        psTCB.views[iView].delta.z = DGN_INT32(temp1);
2210

    
2211
                        psTCB.views[iView].delta.x *= psDGN.scale;
2212
                        psTCB.views[iView].delta.y *= psDGN.scale;
2213
                        psTCB.views[iView].delta.z *= psDGN.scale;
2214

    
2215
                        //memcpy( psTCB.views[iView].transmatrx, pabyRawView + 34, sizeof(double) * 9 );
2216
                        psTCB.views[iView].transmatrx = new double[9];
2217

    
2218
                        for (int k = 0; k < 9; k++) {
2219
                                System.arraycopy(pabyRawView, (34 + (8 * k)), temp1, 0, 8);
2220

    
2221
                                //fin[0]=0;
2222
                                //double d=ByteUtils.bytesToDouble(temp1,fin);
2223
                                fin[0] = 0;
2224
                                psTCB.views[iView].transmatrx[k] = DGNParseIEEE(temp1);
2225

    
2226
                                //nuevo m?todo
2227
                        }
2228

    
2229
                        System.arraycopy(pabyRawView, 106, temp1, 0, 8);
2230
                        fin[0] = 0;
2231
                        psTCB.views[iView].conversion = ByteUtils.bytesToLong(temp1, fin);
2232
                        fin[0] = 0;
2233
                        psTCB.views[iView].conversion = ByteUtils.bytesToDouble(temp1, fin);
2234

    
2235
                        //memcpy( (psTCB.views[iView].conversion), pabyRawView + 106, sizeof(double) );
2236
                        DGNParseIEEE(psTCB.views[iView].conversion);
2237
                        System.arraycopy(pabyRawView, 114, temp1, 0, 8);
2238
                        psTCB.views[iView].activez = DGN_INT32(temp1);
2239
                }
2240

    
2241
                // DGNDumpElement(psDGN, psTCB,"");
2242
                return psTCB;
2243
        }
2244

    
2245
        /**
2246
         * Cambia un entero a LitterIndian.
2247
         *
2248
         * @param x Entero de entrada.
2249
         *
2250
         * @return Entero de salida.
2251
         */
2252
        private int CPL_LSBWORD32(int x) {
2253
                return ((int) ((((int) (x) & (int) 0x000000ff) << 24) |
2254
                (((int) (x) & (int) 0x0000ff00) << 8) |
2255
                (((int) (x) & (int) 0x00ff0000) >> 8) |
2256
                (((int) (x) & (int) 0xff000000) >> 24)));
2257
        }
2258

    
2259
        /**
2260
         * Cambia el vector de char de entrada en el caso de ser null por el
2261
         * caracter vacio.
2262
         *
2263
         * @param pszString Vector de char.
2264
         *
2265
         * @return Vector de char.
2266
         */
2267
        private char[] CPLStrdup(char[] pszString) {
2268
                char[] pszReturn;
2269

    
2270
                if (pszString == null) {
2271
                        pszString[0] = ' ';
2272
                }
2273

    
2274
                pszReturn = new char[pszString.length];
2275

    
2276
                //pszReturn = VSIStrdup( pszString );
2277
                pszReturn = pszString;
2278

    
2279
                if (pszReturn == null) {
2280
                        System.out.println("error");
2281

    
2282
                        /*
2283
                           CPLError( CE_Fatal, CPLE_OutOfMemory,
2284
                                                             "CPLStrdup(): Out of memory allocating %d bytes.\n",
2285
                                                             strlen(pszString) );*/
2286
                }
2287

    
2288
                return (pszReturn);
2289
        }
2290

    
2291
        /**
2292
         * DOCUMENT ME!
2293
         *
2294
         * @param psDGN DOCUMENT ME!
2295
         *
2296
         * @return DOCUMENT ME!
2297
         */
2298
        private DGNElemCore DGNParseTagSet(DGNInfo psDGN) {
2299
                //DGNElemCore psElement;
2300
                DGNElemTagSet psTagSet = new DGNElemTagSet();
2301
                int nDataOffset;
2302
                int iTag;
2303

    
2304
                //psTagSet = (DGNElemTagSet *) CPLCalloc(sizeof(DGNElemTagSet),1);
2305
                //psElement = (DGNElemCore *) psTagSet;
2306
                psTagSet.stype = DGNFileHeader.DGNST_TAG_SET;
2307

    
2308
                DGNParseCore(psDGN, psTagSet);
2309

    
2310
                /* -------------------------------------------------------------------- */
2311
                /*      Parse the overall information.                                  */
2312
                /* -------------------------------------------------------------------- */
2313
                psTagSet.tagCount = ByteUtils.byteToUnsignedInt(psDGN.abyElem[44]) +
2314
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[45]) * 256);
2315
                psTagSet.flags = ByteUtils.byteToUnsignedInt(psDGN.abyElem[46]) +
2316
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[47]) * 256);
2317

    
2318
                int[] fin = new int[1];
2319
                fin[0] = 0;
2320

    
2321
                byte[] temp = new byte[elemento.attr_bytes];
2322
                System.arraycopy(psDGN.abyElem, 48, temp, 0, psDGN.abyElem.length - 48);
2323

    
2324
                psTagSet.tagSetName = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2325
                                                                                                 .toCharArray());
2326

    
2327
                /* -------------------------------------------------------------------- */
2328
                /*      Get the tag set number out of the attributes, if available.     */
2329
                /* -------------------------------------------------------------------- */
2330
                psTagSet.tagSet = -1;
2331

    
2332
                if ((psTagSet.attr_bytes >= 8) &&
2333
                                (psTagSet.attr_data[0] == (byte) 0x03) &&
2334
                                (psTagSet.attr_data[1] == (byte) 0x10) &&
2335
                                (psTagSet.attr_data[2] == (byte) 0x2f) &&
2336
                                (psTagSet.attr_data[3] == (byte) 0x7d)) {
2337
                        psTagSet.tagSet = psTagSet.attr_data[4] +
2338
                                (psTagSet.attr_data[5] * 256);
2339
                }
2340

    
2341
                /* -------------------------------------------------------------------- */
2342
                /*      Parse each of the tag definitions.                              */
2343
                /* -------------------------------------------------------------------- */
2344
                //psTagSet.tagList = (DGNTagDef *)        CPLMalloc(sizeof(DGNTagDef) * psTagSet->tagCount);
2345
                nDataOffset = 48 + psTagSet.tagSetName.length + 1 + 1;
2346

    
2347
                for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2348
                        DGNTagDef tagDef = new DGNTagDef();
2349

    
2350
                        //= psTagSet.tagList + iTag;
2351
                        tagDef.id = iTag;
2352

    
2353
                        //CPLAssert( nDataOffset < psDGN.nElemBytes );
2354
                        /* collect tag name. */
2355
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2356
                                psDGN.abyElem.length);
2357
                        fin[0] = 0;
2358
                        tagDef.name = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2359
                                                                                         .toCharArray());
2360
                        nDataOffset += ((tagDef.name.length) + 1);
2361

    
2362
                        /* Get tag id */
2363
                        tagDef.id = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset]) +
2364
                                (ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2365
                        nDataOffset += 2;
2366

    
2367
                        /* Get User Prompt */
2368
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2369
                                psDGN.abyElem.length);
2370
                        fin[0] = 0;
2371
                        tagDef.prompt = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2372
                                                                                           .toCharArray());
2373
                        nDataOffset += ((tagDef.prompt.length) + 1);
2374

    
2375
                        /* Get type */
2376
                        tagDef.type = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset]) +
2377
                                (ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2378
                        nDataOffset += 2;
2379

    
2380
                        /* skip five zeros */
2381
                        nDataOffset += 5;
2382

    
2383
                        /* Get the default */
2384
                        if (tagDef.type == 1) {
2385
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2386
                                        psDGN.abyElem.length);
2387
                                fin[0] = 0;
2388
                                tagDef.defaultValue.string = CPLStrdup(ByteUtils.bytesToString(
2389
                                                        temp, fin).toCharArray());
2390
                                nDataOffset += (tagDef.defaultValue.string.length + 1);
2391
                        } else if ((tagDef.type == 3) || (tagDef.type == 5)) {
2392
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 4);
2393
                                fin[0] = 0;
2394
                                tagDef.defaultValue.integer = ByteUtils.bytesToLong(temp, fin);
2395

    
2396
                                //memcpy( (tagDef.defaultValue.integer),psDGN.abyElem + nDataOffset, 4 );
2397
                                tagDef.defaultValue.integer = CPL_LSBWORD32((int) tagDef.defaultValue.integer);
2398
                                nDataOffset += 4;
2399
                        } else if (tagDef.type == 4) {
2400
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 8);
2401
                                fin[0] = 0;
2402
                                tagDef.defaultValue.real = ByteUtils.bytesToDouble(temp, fin);
2403

    
2404
                                //memcpy( (tagDef.defaultValue.real),        psDGN.abyElem + nDataOffset, 8 );
2405
                                DGNParseIEEE(tagDef.defaultValue.real);
2406
                                nDataOffset += 8;
2407
                        } else {
2408
                                nDataOffset += 4;
2409
                        }
2410
                }
2411

    
2412
                return psTagSet;
2413
        }
2414

    
2415
        /**
2416
         * DOCUMENT ME!
2417
         *
2418
         * @param psDGN DOCUMENT ME!
2419
         * @param nOptions DOCUMENT ME!
2420
         */
2421
        private void DGNSetOptions(DGNInfo psDGN, int nOptions) {
2422
                psDGN.options = nOptions;
2423
        }
2424

    
2425
        /**
2426
         * DOCUMENT ME!
2427
         *
2428
         * @param psDGN DOCUMENT ME!
2429
         * @param dfXMin DOCUMENT ME!
2430
         * @param dfYMin DOCUMENT ME!
2431
         * @param dfXMax DOCUMENT ME!
2432
         * @param dfYMax DOCUMENT ME!
2433
         */
2434
        private void DGNSetSpatialFilter(DGNInfo psDGN, double dfXMin,
2435
                double dfYMin, double dfXMax, double dfYMax) {
2436
                if ((dfXMin == 0.0) && (dfXMax == 0.0) && (dfYMin == 0.0) &&
2437
                                (dfYMax == 0.0)) {
2438
                        psDGN.has_spatial_filter = FALSE;
2439

    
2440
                        return;
2441
                }
2442

    
2443
                psDGN.has_spatial_filter = TRUE;
2444
                psDGN.sf_converted_to_uor = FALSE;
2445

    
2446
                psDGN.sf_min_x_geo = dfXMin;
2447
                psDGN.sf_min_y_geo = dfYMin;
2448
                psDGN.sf_max_x_geo = dfXMax;
2449
                psDGN.sf_max_y_geo = dfYMax;
2450

    
2451
                DGNSpatialFilterToUOR(psDGN);
2452
        }
2453

    
2454
        /**
2455
         * Muestra por consola los elementos que contiene el DGN.
2456
         *
2457
         * @param psInfo Informaci?n del DGN.
2458
         * @param psElement elemento
2459
         * @param fp path del fichero.
2460
         */
2461
        public void DGNDumpElement(DGNInfo psInfo, DGNElemCore psElement, String fp) {
2462
                //DGNInfo *psInfo = (DGNInfo *) hDGN;
2463
                //System.out.println("\n");
2464
                System.out.println("Element:" + DGNTypeToName(psElement.type) +
2465
                        " Level:" + psElement.level + " id:" + psElement.element_id);
2466

    
2467
                if (psElement.complex != 0) {
2468
                        System.out.println("(Complex) ");
2469
                }
2470

    
2471
                if (psElement.deleted != 0) {
2472
                        System.out.println("(DELETED) ");
2473
                }
2474

    
2475
                System.out.println("  offset=" + psElement.offset + " size=" +
2476
                        psElement.size + " bytes\n");
2477

    
2478
                System.out.println("  graphic_group:" + psElement.graphic_group +
2479
                        " color:" + psElement.color + " weight:" + psElement.weight +
2480
                        "style:" + psElement.style + "\n");
2481

    
2482
                if (psElement.properties != 0) {
2483
                        int nClass;
2484

    
2485
                        System.out.println("  properties=" + psElement.properties);
2486

    
2487
                        if ((psElement.properties & DGNFileHeader.DGNPF_HOLE) != 0) {
2488
                                System.out.println(",HOLE");
2489
                        }
2490

    
2491
                        if ((psElement.properties & DGNFileHeader.DGNPF_SNAPPABLE) != 0) {
2492
                                System.out.println(",SNAPPABLE");
2493
                        }
2494

    
2495
                        if ((psElement.properties & DGNFileHeader.DGNPF_PLANAR) != 0) {
2496
                                System.out.println(",PLANAR");
2497
                        }
2498

    
2499
                        if ((psElement.properties & DGNFileHeader.DGNPF_ORIENTATION) != 0) {
2500
                                System.out.println(",ORIENTATION");
2501
                        }
2502

    
2503
                        if ((psElement.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
2504
                                System.out.println(",ATTRIBUTES");
2505
                        }
2506

    
2507
                        if ((psElement.properties & DGNFileHeader.DGNPF_MODIFIED) != 0) {
2508
                                System.out.println(",MODIFIED");
2509
                        }
2510

    
2511
                        if ((psElement.properties & DGNFileHeader.DGNPF_NEW) != 0) {
2512
                                System.out.println(",NEW");
2513
                        }
2514

    
2515
                        if ((psElement.properties & DGNFileHeader.DGNPF_LOCKED) != 0) {
2516
                                System.out.println(",LOCKED");
2517
                        }
2518

    
2519
                        nClass = psElement.properties & DGNFileHeader.DGNPF_CLASS;
2520

    
2521
                        if (nClass == DGNFileHeader.DGNC_PATTERN_COMPONENT) {
2522
                                System.out.println(",PATTERN_COMPONENT");
2523
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_ELEMENT) {
2524
                                System.out.println(",CONSTRUCTION ELEMENT");
2525
                        } else if (nClass == DGNFileHeader.DGNC_DIMENSION_ELEMENT) {
2526
                                System.out.println(",DIMENSION ELEMENT");
2527
                        } else if (nClass == DGNFileHeader.DGNC_PRIMARY_RULE_ELEMENT) {
2528
                                System.out.println(",PRIMARY RULE ELEMENT");
2529
                        } else if (nClass == DGNFileHeader.DGNC_LINEAR_PATTERNED_ELEMENT) {
2530
                                System.out.println(",LINEAR PATTERNED ELEMENT");
2531
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_RULE_ELEMENT) {
2532
                                System.out.println(",CONSTRUCTION_RULE_ELEMENT");
2533
                        }
2534

    
2535
                        // System.out.println("\n");
2536
                }
2537

    
2538
                switch (psElement.stype) {
2539
                        case DGNFileHeader.DGNST_MULTIPOINT: {
2540
                                DGNElemMultiPoint psLine = new DGNElemMultiPoint();
2541
                                psLine = (DGNElemMultiPoint) psElement;
2542

    
2543
                                int i;
2544

    
2545
                                for (i = 0; i < psLine.num_vertices; i++)
2546
                                        System.out.println(psLine.vertices[i].x + "," +
2547
                                                psLine.vertices[i].y + "," + psLine.vertices[i].z);
2548
                        }
2549

    
2550
                        break;
2551

    
2552
                        case DGNFileHeader.DGNST_CELL_HEADER: {
2553
                                DGNElemCellHeader psCell = new DGNElemCellHeader();
2554
                                psCell = (DGNElemCellHeader) psElement;
2555

    
2556
                                System.out.println("  totlength=" + psCell.totlength +
2557
                                        ", name=" + psCell.name.toString() + " class=" +
2558
                                        psCell.cclass + " levels=" + psCell.levels[0] +
2559
                                        psCell.levels[1] + psCell.levels[2] + psCell.levels[3] +
2560
                                        "\n");
2561
                                System.out.println("  rnglow=(" + psCell.rnglow.x + "," +
2562
                                        psCell.rnglow.y + "), rnghigh=(" + psCell.rnghigh.x + "," +
2563
                                        psCell.rnghigh.y + ")\n");
2564
                                System.out.println("  origin=(" + psCell.origin.x + "," +
2565
                                        psCell.origin.y + ")\n");
2566
                                System.out.println("  xscale=" + psCell.xscale + ",yscale=" +
2567
                                        psCell.yscale + ", rotation=" + psCell.rotation + "\n");
2568
                        }
2569

    
2570
                        break;
2571

    
2572
                        case DGNFileHeader.DGNST_CELL_LIBRARY: {
2573
                                DGNElemCellLibrary psCell = new DGNElemCellLibrary();
2574
                                psCell = (DGNElemCellLibrary) psElement;
2575

    
2576
                                System.out.println("  name=" + psCell.name.toString() +
2577
                                        " class=" + psCell.cclass + " levels=" + psCell.levels[0] +
2578
                                        psCell.levels[1] + psCell.levels[2] + psCell.levels[3] +
2579
                                        " numwords=" + psCell.numwords + "\n");
2580
                                System.out.println("  dispsymb=" + psCell.dispsymb +
2581
                                        ", description=" + psCell.description + "\n");
2582
                        }
2583

    
2584
                        break;
2585

    
2586
                        case DGNFileHeader.DGNST_ARC: {
2587
                                DGNElemArc psArc = new DGNElemArc();
2588
                                psArc = (DGNElemArc) psElement;
2589

    
2590
                                if (psInfo.dimension == 2) {
2591
                                        System.out.println("  origin=(" + psArc.origin.x + "," +
2592
                                                psArc.origin.y + "), rotation=" + psArc.rotation +
2593
                                                "\n");
2594
                                } else {
2595
                                        System.out.println("  origin=(" + psArc.origin.x + "," +
2596
                                                psArc.origin.y + "," + psArc.origin.z + "), quat=" +
2597
                                                psArc.quat[0] + "," + psArc.quat[1] + "," +
2598
                                                psArc.quat[2] + "," + psArc.quat[3] + "\n");
2599
                                }
2600

    
2601
                                System.out.println("  axes=(" + psArc.primary_axis + "," +
2602
                                        psArc.secondary_axis + "), start angle=" + psArc.startang +
2603
                                        ", sweep=" + psArc.sweepang + "\n");
2604
                        }
2605

    
2606
                        break;
2607

    
2608
                        case DGNFileHeader.DGNST_TEXT: {
2609
                                DGNElemText psText = new DGNElemText();
2610
                                psText = (DGNElemText) psElement;
2611

    
2612
                                System.out.println("  origin=(" + psText.origin.x +
2613
                                        psText.origin.y + ") rotation=" + psText.rotation + "\n" +
2614
                                        "  font=" + psText.font_id + " just=" +
2615
                                        psText.justification + "length_mult=" + psText.length_mult +
2616
                                        " height_mult=" + psText.height_mult + "\n" + "  string =" +
2617
                                        new String(psText.string).toString() + "\n");
2618
                        }
2619

    
2620
                        break;
2621

    
2622
                        case DGNFileHeader.DGNST_COMPLEX_HEADER: {
2623
                                DGNElemComplexHeader psHdr = new DGNElemComplexHeader();
2624
                                psHdr = (DGNElemComplexHeader) psElement;
2625

    
2626
                                System.out.println("  totlength=" + psHdr.totlength +
2627
                                        "numelems=" + psHdr.numelems + "\n");
2628
                        }
2629

    
2630
                        break;
2631

    
2632
                        case DGNFileHeader.DGNST_COLORTABLE: {
2633
                                DGNElemColorTable psCT = new DGNElemColorTable();
2634
                                psCT = (DGNElemColorTable) psElement;
2635

    
2636
                                int i;
2637

    
2638
                                System.out.println("  screen_flag:" + psCT.screen_flag + "\n");
2639

    
2640
                                for (i = 0; i < 256; i++) {
2641
                                        System.out.println(i + ": (" + psCT.color_info[i][0] + "," +
2642
                                                psCT.color_info[i][1] + "," + psCT.color_info[i][2] +
2643
                                                ")\n");
2644
                                }
2645
                        }
2646

    
2647
                        break;
2648

    
2649
                        case DGNFileHeader.DGNST_TCB: {
2650
                                DGNElemTCB psTCB = new DGNElemTCB();
2651
                                psTCB = (DGNElemTCB) psElement;
2652

    
2653
                                int iView;
2654

    
2655
                                //psTCB.dimension=psInfo.dimension;
2656
                                System.out.println("  dimension =" + psTCB.dimension + "\n");
2657
                                System.out.println("  uor_per_subunit =" +
2658
                                        psTCB.uor_per_subunit); //+
2659

    
2660
                                // " subunits = `" + psTCB.sub_units[0] + psTCB.sub_units[1] +
2661
                                // psTCB.sub_units[2] + "'\n");
2662
                                System.out.println("  subunits_per_master =" +
2663
                                        psTCB.subunits_per_master); //+ " master_units = `" +
2664

    
2665
                                // psTCB.master_units[0] + psTCB.master_units[1] +
2666
                                // psTCB.master_units[2] + "'\n");
2667
                                System.out.println("  origin = (" + psTCB.origin_x + "," +
2668
                                        psTCB.origin_y + "," + psTCB.origin_z + ")\n");
2669

    
2670
                                for (iView = 0; iView < 8; iView++) {
2671
                                        DGNViewInfo psView = psTCB.views[iView];
2672

    
2673
                                        //DGNParseTCB(psInfo);
2674
                                        System.out.println("View  " + iView + ": flags= " +
2675
                                                Integer.toHexString(psView.flags) + " levels= " +
2676
                                                psView.levels[0] + "" + psView.levels[1] + "" +
2677
                                                psView.levels[2] + "" + psView.levels[3] + "" +
2678
                                                psView.levels[4] + "" + psView.levels[5] + "" +
2679
                                                psView.levels[6] + "" + psView.levels[7] + "\n");
2680
                                        System.out.println("origin=( " + psView.origin.x + "," +
2681
                                                psView.origin.y + "," + psView.origin.z +
2682
                                                ")\n        delta=(" + psView.delta.x + "," +
2683
                                                psView.delta.y + "," + psView.delta.z + ")\n");
2684

    
2685
                                        System.out.println("trans=( " + psView.transmatrx[0] + "," +
2686
                                                psView.transmatrx[1] + "," + psView.transmatrx[2] +
2687
                                                "," + psView.transmatrx[3] + "," +
2688
                                                psView.transmatrx[4] + "," + psView.transmatrx[5] +
2689
                                                "," + psView.transmatrx[6] + "," +
2690
                                                psView.transmatrx[7] + "," + psView.transmatrx[8] +
2691
                                                ")\n");
2692
                                }
2693
                        }
2694

    
2695
                        break;
2696

    
2697
                        case DGNFileHeader.DGNST_TAG_SET: {
2698
                                DGNElemTagSet psTagSet = new DGNElemTagSet();
2699
                                psTagSet = (DGNElemTagSet) psElement;
2700

    
2701
                                int iTag;
2702

    
2703
                                System.out.println("  tagSetName=" +
2704
                                        psTagSet.tagSetName.toString() + " tagSet=" +
2705
                                        psTagSet.tagSet + " tagCount=" + psTagSet.tagCount +
2706
                                        " flags=" + psTagSet.flags + "\n");
2707

    
2708
                                for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2709
                                        DGNTagDef psTagDef = psTagSet.tagList[iTag];
2710

    
2711
                                        System.out.println(psTagDef.id + ": name=" +
2712
                                                psTagDef.name.toString() + ", type=" + psTagDef.type +
2713
                                                ", prompt=" + psTagDef.prompt.toString());
2714

    
2715
                                        if (psTagDef.type == 1) {
2716
                                                System.out.println(", default=" +
2717
                                                        psTagDef.defaultValue.string.toString() + "\n");
2718
                                        } else if ((psTagDef.type == 3) || (psTagDef.type == 5)) {
2719
                                                System.out.println(", default=" +
2720
                                                        psTagDef.defaultValue.integer + "\n");
2721
                                        } else if (psTagDef.type == 4) {
2722
                                                System.out.println(", default=" +
2723
                                                        psTagDef.defaultValue.real + "\n");
2724
                                        } else {
2725
                                                System.out.println(", default=<unknown>\n");
2726
                                        }
2727
                                }
2728
                        }
2729

    
2730
                        break;
2731

    
2732
                        case DGNFileHeader.DGNST_TAG_VALUE: {
2733
                                DGNElemTagValue psTag = new DGNElemTagValue();
2734
                                psTag = (DGNElemTagValue) psElement;
2735

    
2736
                                System.out.println("  tagType=" + psTag.tagType + ", tagSet=" +
2737
                                        psTag.tagSet + ", tagIndex=" + psTag.tagIndex +
2738
                                        ", tagLength=" + psTag.tagLength + "\n");
2739

    
2740
                                if (psTag.tagType == 1) {
2741
                                        System.out.println("  value=" +
2742
                                                psTag.tagValue.string.toString() + "\n");
2743
                                } else if (psTag.tagType == 3) {
2744
                                        System.out.println("  value=" + psTag.tagValue.integer +
2745
                                                "\n");
2746
                                } else if (psTag.tagType == 4) {
2747
                                        System.out.println("  value=" + psTag.tagValue.real + "\n");
2748
                                }
2749
                        }
2750

    
2751
                        break;
2752

    
2753
                        case DGNFileHeader.DGNST_GROUP_DATA: {
2754
                                // TODO
2755
                        }
2756

    
2757
                        break;
2758

    
2759
                        default:
2760
                                break;
2761
                }
2762

    
2763
                if (psElement.attr_bytes > 0) {
2764
                        int iLink;
2765

    
2766
                        System.out.println("Attributes:" + psElement.attr_bytes + "\n");
2767

    
2768
                        for (iLink = 0; true; iLink++) {
2769
                                int[] nLinkType = new int[1];
2770
                                int[] nEntityNum = new int[1];
2771
                                int[] nMSLink = new int[1];
2772
                                int[] nLinkSize = new int[1];
2773
                                int i;
2774
                                nEntityNum[0] = 0;
2775
                                nMSLink[0] = 0;
2776

    
2777
                                byte[] pabyData;
2778

    
2779
                                pabyData = DGNGetLinkage(psInfo, psElement, iLink, nLinkType,
2780
                                                nEntityNum, nMSLink, nLinkSize);
2781

    
2782
                                if (pabyData == null) {
2783
                                        break;
2784
                                }
2785

    
2786
                                System.out.println("Type=0x" + nLinkType);
2787

    
2788
                                if ((nMSLink[0] != 0) || (nEntityNum[0] != 0)) {
2789
                                        System.out.println(", EntityNum=" + nEntityNum[0] +
2790
                                                ", MSLink=" + nMSLink[0]);
2791
                                }
2792

    
2793
                                System.out.println("\n  0x");
2794

    
2795
                                for (i = 0; i < nLinkSize[0]; i++)
2796
                                        System.out.println(pabyData[i]);
2797

    
2798
                                System.out.println("\n");
2799
                        }
2800
                }
2801
        }
2802

    
2803
        /**
2804
         * Returns requested linkage raw data.  A pointer to the raw data for the
2805
         * requested attribute linkage is returned as well as (potentially)
2806
         * various information about the linkage including the linkage type,
2807
         * database entity number and MSLink value, and the length of the raw
2808
         * linkage data in bytes. If the requested linkage (iIndex) does not exist
2809
         * a value of zero is  returned. The entity number is (loosely speaking)
2810
         * the index of the table within the current database to which the MSLINK
2811
         * value will refer.  The entity number should be used to lookup the table
2812
         * name in the MSCATALOG table.  The MSLINK value is the key value for the
2813
         * record in the target table.
2814
         *
2815
         * @param psDGN the file from which the element originated.
2816
         * @param psElement the element to report on.
2817
         * @param iIndex the zero based index of the linkage to fetch.
2818
         * @param pnLinkageType variable to return linkage type.  This may be one
2819
         *                   of the predefined DGNLT_ values or a different value. This
2820
         *                   pointer may be NULL.
2821
         * @param pnEntityNum variable to return the entity number in or NULL if
2822
         *                   not required.
2823
         * @param pnMSLink variable to return the MSLINK value in, or NULL if not
2824
         *                   required.
2825
         * @param pnLength variable to returned the linkage size in bytes or NULL.
2826
         *
2827
         * @return pointer to raw internal linkage data.  This data should not be
2828
         *                    altered or freed.  NULL returned on failure.
2829
         */
2830
        private byte[] DGNGetLinkage(DGNInfo psDGN, DGNElemCore psElement,
2831
                int iIndex, int[] pnLinkageType, int[] pnEntityNum, int[] pnMSLink,
2832
                int[] pnLength) {
2833
                int nAttrOffset;
2834
                int iLinkage;
2835
                int nLinkSize;
2836

    
2837
                for (iLinkage = 0, nAttrOffset = 0;
2838
                                (nLinkSize = DGNGetAttrLinkSize(psDGN, psElement, nAttrOffset)) != 0;
2839
                                iLinkage++, nAttrOffset += nLinkSize) {
2840
                        if (iLinkage == iIndex) {
2841
                                int nLinkageType = 0;
2842
                                int nEntityNum = 0;
2843
                                int nMSLink = 0;
2844

    
2845
                                //CPLAssert( nLinkSize > 4 );
2846
                                if ((psElement.attr_data[nAttrOffset + 0] == (byte) 0x00) &&
2847
                                                ((psElement.attr_data[nAttrOffset + 1] == (byte) 0x00) ||
2848
                                                (psElement.attr_data[nAttrOffset + 1] == (byte) 0x80))) {
2849
                                        nLinkageType = DGNFileHeader.DGNLT_DMRS;
2850
                                        nEntityNum = psElement.attr_data[nAttrOffset + 2] +
2851
                                                (psElement.attr_data[nAttrOffset + 3] * 256);
2852
                                        nMSLink = psElement.attr_data[nAttrOffset + 4] +
2853
                                                (psElement.attr_data[nAttrOffset + 5] * 256) +
2854
                                                (psElement.attr_data[nAttrOffset + 6] * 65536);
2855
                                } else {
2856
                                        nLinkageType = psElement.attr_data[nAttrOffset + 2] +
2857
                                                (psElement.attr_data[nAttrOffset + 3] * 256);
2858
                                }
2859

    
2860
                                // Possibly an external database linkage?
2861
                                if ((nLinkSize == 16) &&
2862
                                                (nLinkageType != DGNFileHeader.DGNLT_SHAPE_FILL)) {
2863
                                        nEntityNum = psElement.attr_data[nAttrOffset + 6] +
2864
                                                (psElement.attr_data[nAttrOffset + 7] * 256);
2865
                                        nMSLink = psElement.attr_data[nAttrOffset + 8] +
2866
                                                (psElement.attr_data[nAttrOffset + 9] * 256) +
2867
                                                (psElement.attr_data[nAttrOffset + 10] * 65536) +
2868
                                                (psElement.attr_data[nAttrOffset + 11] * 65536 * 256);
2869
                                }
2870

    
2871
                                if (pnLinkageType != null) {
2872
                                        pnLinkageType[0] = nLinkageType;
2873
                                }
2874

    
2875
                                if (pnEntityNum != null) {
2876
                                        pnEntityNum[0] = nEntityNum;
2877
                                }
2878

    
2879
                                if (pnMSLink != null) {
2880
                                        pnMSLink[0] = nMSLink;
2881
                                }
2882

    
2883
                                if (pnLength != null) {
2884
                                        pnLength[0] = nLinkSize;
2885
                                }
2886

    
2887
                                byte[] temp = new byte[psElement.attr_data.length -
2888
                                        nAttrOffset];
2889
                                System.arraycopy(psElement.attr_data, nAttrOffset, temp, 0,
2890
                                        psElement.attr_data.length - nAttrOffset);
2891

    
2892
                                return temp;
2893
                        }
2894
                }
2895

    
2896
                return null;
2897
        }
2898

    
2899
        /**
2900
         * Devuelve el tama?o de los atributos de un elemento.
2901
         *
2902
         * @param psDGN Informaci?n del DGN.
2903
         * @param psElement elemento.
2904
         * @param nOffset indice donde se encuentra el elemento.
2905
         *
2906
         * @return Entero que representa el Tama?o.
2907
         */
2908
        private int DGNGetAttrLinkSize(DGNInfo psDGN, DGNElemCore psElement,
2909
                int nOffset) {
2910
                if (psElement.attr_bytes < (nOffset + 4)) {
2911
                        return 0;
2912
                }
2913

    
2914
                /* DMRS Linkage */
2915
                if (((psElement.attr_data[nOffset + 0] == 0) &&
2916
                                (psElement.attr_data[nOffset + 1] == 0)) ||
2917
                                ((psElement.attr_data[nOffset + 0] == 0) &&
2918
                                (psElement.attr_data[nOffset + 1] == (byte) 0x80))) {
2919
                        return 8;
2920
                }
2921

    
2922
                /* If low order bit of second byte is set, first byte is length */
2923
                if ((psElement.attr_data[nOffset + 1] & (byte) 0x10) != FALSE) {
2924
                        return (psElement.attr_data[nOffset + 0] * 2) + 2;
2925
                }
2926

    
2927
                /* unknown */
2928
                return 0;
2929
        }
2930

    
2931
        /**
2932
         * A partir de un entero devuelve el un String con el tipo del elemento.
2933
         *
2934
         * @param nType tipo.
2935
         *
2936
         * @return String con el nombre del elemento.
2937
         */
2938
        private String DGNTypeToName(int nType) {
2939
                //char[]        szNumericResult=new char[16];
2940
                switch (nType) {
2941
                        case DGNFileHeader.DGNT_CELL_LIBRARY:
2942
                                return "Cell Library";
2943

    
2944
                        case DGNFileHeader.DGNT_CELL_HEADER:
2945
                                return "Cell Header";
2946

    
2947
                        case DGNFileHeader.DGNT_LINE:
2948
                                return "Line";
2949

    
2950
                        case DGNFileHeader.DGNT_LINE_STRING:
2951
                                return "Line String";
2952

    
2953
                        case DGNFileHeader.DGNT_GROUP_DATA:
2954
                                return "Group Data";
2955

    
2956
                        case DGNFileHeader.DGNT_SHAPE:
2957
                                return "Shape";
2958

    
2959
                        case DGNFileHeader.DGNT_TEXT_NODE:
2960
                                return "Text Node";
2961

    
2962
                        case DGNFileHeader.DGNT_DIGITIZER_SETUP:
2963
                                return "Digitizer Setup";
2964

    
2965
                        case DGNFileHeader.DGNT_TCB:
2966
                                return "TCB";
2967

    
2968
                        case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
2969
                                return "Level Symbology";
2970

    
2971
                        case DGNFileHeader.DGNT_CURVE:
2972
                                return "Curve";
2973

    
2974
                        case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
2975
                                return "Complex Chain Header";
2976

    
2977
                        case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
2978
                                return "Complex Shape Header";
2979

    
2980
                        case DGNFileHeader.DGNT_ELLIPSE:
2981
                                return "Ellipse";
2982

    
2983
                        case DGNFileHeader.DGNT_ARC:
2984
                                return "Arc";
2985

    
2986
                        case DGNFileHeader.DGNT_TEXT:
2987
                                return "Text";
2988

    
2989
                        case DGNFileHeader.DGNT_BSPLINE:
2990
                                return "B-Spline";
2991

    
2992
                        case DGNFileHeader.DGNT_APPLICATION_ELEM:
2993
                                return "Application Element";
2994

    
2995
                        case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
2996
                                return "Shared Cell Definition";
2997

    
2998
                        case DGNFileHeader.DGNT_SHARED_CELL_ELEM:
2999
                                return "Shared Cell Element";
3000

    
3001
                        case DGNFileHeader.DGNT_TAG_VALUE:
3002
                                return "Tag Value";
3003

    
3004
                        default:
3005
                                System.out.println(nType);
3006

    
3007
                                return "Fallo";
3008
                }
3009
        }
3010

    
3011
        /**
3012
         * Muestra por consola la fila de un elemento.
3013
         *
3014
         * @param psDGN informaci?n del DGN.
3015
         * @param psCore elemento
3016
         * @param fpOut path del fichero DGN.
3017
         */
3018
        private void DGNDumpRawElement(DGNInfo psDGN, DGNElemCore psCore,
3019
                String fpOut) {
3020
                int i;
3021
                int iChar = 0;
3022
                byte[] szLine = new byte[80];
3023

    
3024
                //System.out.println("  Raw Data (" + psCore.raw_bytes + " bytes):\n");
3025
                for (i = 0; i < psCore.raw_bytes; i++) {
3026
                        byte[] szHex = new byte[3];
3027

    
3028
                        if ((i % 16) == 0) {
3029
                                int[] f = new int[1];
3030
                                byte[] temp = new byte[4];
3031
                                f[0] = 0;
3032
                                ByteUtils.intToBytes(i, temp, f);
3033
                                System.arraycopy(temp, 0, szLine, 0, 4);
3034

    
3035
                                ////System.out.println( szLine.toString()+","+ i );
3036
                                iChar = 0;
3037
                        }
3038

    
3039
                        szHex[0] = psCore.raw_data[i];
3040
                        szHex[1] = (byte) 0x00;
3041

    
3042
                        //System.arraycopy(psCore.raw_data,0,szHex,0,3);
3043
                        ////System.out.println( szHex.toString()+","+psCore.raw_data.toString() );
3044
                        //strncpy( szLine+8+iChar*2, szHex, 2 );/**no se */
3045
                        System.arraycopy(szHex, 0, szLine, 8 + (iChar * 2), 2);
3046

    
3047
                        if ((psCore.raw_data[i] < 32) || (psCore.raw_data[i] > 127)) {
3048
                                szLine[42 + iChar] = '.';
3049
                        } else {
3050
                                szLine[42 + iChar] = psCore.raw_data[i];
3051
                        }
3052

    
3053
                        if ((i == (psCore.raw_bytes - 1)) || (((i + 1) % 16) == 0)) {
3054
                                ////System.out.println(szLine.toString()+"\n" );
3055
                                int[] f = new int[1];
3056
                                f[0] = 0;
3057

    
3058
                                //ByteUtils.bytesToInt(szLine,f);
3059
                                //System.out.println(ByteUtils.bytesToInt(szLine, f) + " : ");
3060
                                //ByteUtils.print_bytes(szLine,8,74);
3061
                                byte[] temp = new byte[1];
3062
                                byte[] temp1 = new byte[16];
3063
                                int k = 0;
3064

    
3065
                                for (int j = 1; j < 32; j = j + 2) {
3066
                                        System.arraycopy(szLine, j + 7, temp, 0, 1);
3067
                                        temp1[k] = temp[0];
3068
                                        k++;
3069
                                }
3070

    
3071
                                //System.out.println(ByteUtils.print_bytes(temp1));
3072
                                ////System.out.println(ByteUtils.print_bytes(szLine,7,41));
3073
                                f[0] = 42;
3074

    
3075
                                char[] tempchar = new char[16];
3076

    
3077
                                for (int j = 0; j < 16; j++) {
3078
                                        tempchar[j] = (char) szLine[42 + j];
3079
                                }
3080

    
3081
                                //System.out.println(String.copyValueOf(tempchar));
3082
                        }
3083

    
3084
                        iChar++;
3085
                }
3086
        }
3087

    
3088
        /**
3089
         * Devuelve el extent del elemento.
3090
         *
3091
         * @param psDGN Informaci?n del DGN.
3092
         * @param padfExtents doubles que representan el rect?ngulo del extent.
3093
         *
3094
         * @return Entero que muestra si se ha calculado correctamente.
3095
         */
3096
        private int DGNGetExtents(DGNInfo psDGN, double[] padfExtents) {
3097
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3098
                DGNPoint sMin = new DGNPoint();
3099
                DGNPoint sMax = new DGNPoint();
3100

    
3101
                DGNBuildIndex(psDGN);
3102

    
3103
                if (psDGN.got_bounds == FALSE) {
3104
                        return FALSE;
3105
                }
3106

    
3107
                double minX = psDGN.min_x;
3108
                double minY = psDGN.min_y;
3109
                double minZ = psDGN.min_z;
3110
                System.out.println("psDGN.min" + " x= " + psDGN.min_x + " y= " +
3111
                        psDGN.min_y);
3112

    
3113
                if (minX < 0) {
3114
                        minX = minX + (2 * ((long) Integer.MAX_VALUE + 1));
3115
                        System.out.println("minX" + minX);
3116
                }
3117

    
3118
                if (minY < 0) {
3119
                        minY = minY + (2 * ((long) Integer.MAX_VALUE + 1));
3120
                        System.out.println("minY" + minY);
3121
                }
3122

    
3123
                if (minZ < 0) {
3124
                        minZ = minZ + (2 * ((long) Integer.MAX_VALUE + 1));
3125
                }
3126

    
3127
                sMin.x = minX - 2147483648.0;
3128
                sMin.y = minY - 2147483648.0;
3129
                sMin.z = minZ - 2147483648.0;
3130

    
3131
                DGNTransformPoint(psDGN, sMin);
3132

    
3133
                padfExtents[0] = sMin.x;
3134
                padfExtents[1] = sMin.y;
3135
                padfExtents[2] = sMin.z;
3136

    
3137
                double maxX = psDGN.max_x;
3138
                double maxY = psDGN.max_y;
3139
                double maxZ = psDGN.max_z;
3140

    
3141
                //System.out.println("psDGN.max"+ " x= "+psDGN.max_x+" y= "+psDGN.max_y);
3142
                if (maxX < 0) {
3143
                        maxX = maxX + (2 * ((long) Integer.MAX_VALUE + 1));
3144

    
3145
                        //System.out.println("maxX"+maxX);
3146
                }
3147

    
3148
                if (maxY < 0) {
3149
                        maxY = maxY + (2 * ((long) Integer.MAX_VALUE + 1));
3150

    
3151
                        //System.out.println("maxY"+maxY);
3152
                }
3153

    
3154
                if (maxZ < 0) {
3155
                        maxZ = maxZ + (2 * ((long) Integer.MAX_VALUE + 1));
3156
                }
3157

    
3158
                sMax.x = maxX - 2147483648.0;
3159
                sMax.y = maxY - 2147483648.0;
3160
                sMax.z = maxZ - 2147483648.0;
3161

    
3162
                DGNTransformPoint(psDGN, sMax);
3163

    
3164
                padfExtents[3] = sMax.x;
3165
                padfExtents[4] = sMax.y;
3166
                padfExtents[5] = sMax.z;
3167

    
3168
                return TRUE;
3169
        }
3170

    
3171
        /**
3172
         * Construye un ?ndice al DGN.
3173
         *
3174
         * @param psDGN Informaci?n del DGN.
3175
         */
3176
        private void DGNBuildIndex(DGNInfo psDGN) {
3177
                DGNElemCore elemento = new DGNElemCore();
3178
                int nMaxElements;
3179
                int nType;
3180
                int nLevel;
3181
                long nLastOffset;
3182

    
3183
                if (psDGN.index_built != FALSE) {
3184
                        return;
3185
                }
3186

    
3187
                psDGN.index_built = TRUE;
3188

    
3189
                //DGNRewind( psDGN );
3190
                nMaxElements = 0;
3191

    
3192
                //nLastOffset = VSIFTell( psDGN.fp );
3193
                nLastOffset = bb.position(); //psDGN.ftall;
3194

    
3195
                while (DGNLoadRawElement(psDGN, elemento) != FALSE) {
3196
                        DGNElementInfo psEI; // = new DGNElementInfo();
3197

    
3198
                        if (psDGN.element_count == nMaxElements) {
3199
                                int oldMax = nMaxElements;
3200
                                nMaxElements = (int) (nMaxElements * 1.5) + 500;
3201

    
3202
                                DGNElementInfo[] nuevo = new DGNElementInfo[nMaxElements];
3203

    
3204
                                for (int i = 0; i < oldMax; i++)
3205
                                        nuevo[i] = psDGN.element_index[i];
3206

    
3207
                                psDGN.element_index = nuevo;
3208

    
3209
                                //psDGN.element_index = (DGNElementInfo *)        CPLRealloc( psDGN.element_index,
3210
                                //                                nMaxElements * sizeof(DGNElementInfo) );
3211
                        }
3212

    
3213
                        psDGN.element_index[psDGN.element_count] = new DGNElementInfo();
3214
                        psEI = psDGN.element_index[psDGN.element_count];
3215
                        psEI.level = elemento.level;
3216
                        psEI.type = elemento.type;
3217
                        psEI.flags = 0;
3218
                        psEI.offset = nLastOffset;
3219

    
3220
                        if ((psDGN.abyElem[0] * (byte) 0x80) == (byte) 0x80) {
3221
                                psEI.flags |= DGNFileHeader.DGNEIF_COMPLEX;
3222
                        }
3223

    
3224
                        if ((psDGN.abyElem[1] * (byte) 0x80) == (byte) 0x80) {
3225
                                psEI.flags |= DGNFileHeader.DGNEIF_DELETED;
3226
                        }
3227

    
3228
                        if ((elemento.type == DGNFileHeader.DGNT_LINE) ||
3229
                                        (elemento.type == DGNFileHeader.DGNT_LINE_STRING) ||
3230
                                        (elemento.type == DGNFileHeader.DGNT_SHAPE) ||
3231
                                        (elemento.type == DGNFileHeader.DGNT_CURVE) ||
3232
                                        (elemento.type == DGNFileHeader.DGNT_BSPLINE)) {
3233
                                psEI.stype = DGNFileHeader.DGNST_MULTIPOINT;
3234
                        } else if ((elemento.type == DGNFileHeader.DGNT_GROUP_DATA) &&
3235
                                        (elemento.level == DGNFileHeader.DGN_GDL_COLOR_TABLE)) {
3236
                                DGNElemCore psCT = DGNParseColorTable(psDGN);
3237

    
3238
                                //DGNFreeElement( psDGN, psCT );
3239
                                System.err.println("TABLA DE COLORES!!");
3240
                                psEI.stype = DGNFileHeader.DGNST_COLORTABLE;
3241
                                m_colorTable = (DGNElemColorTable) psCT;
3242

    
3243
                                // DGNDumpElement(psDGN,psCT,"");
3244
                        } else if ((elemento.type == DGNFileHeader.DGNT_ELLIPSE) ||
3245
                                        (elemento.type == DGNFileHeader.DGNT_ARC)) {
3246
                                psEI.stype = DGNFileHeader.DGNST_ARC;
3247
                        } else if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) ||
3248
                                        (elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)) {
3249
                                psEI.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
3250
                        } else if (elemento.type == DGNFileHeader.DGNT_TEXT) {
3251
                                psEI.stype = DGNFileHeader.DGNST_TEXT;
3252
                        } else if (elemento.type == DGNFileHeader.DGNT_TAG_VALUE) {
3253
                                psEI.stype = DGNFileHeader.DGNST_TAG_VALUE;
3254
                        } else if (elemento.type == DGNFileHeader.DGNT_APPLICATION_ELEM) {
3255
                                if (elemento.level == 24) {
3256
                                        psEI.stype = DGNFileHeader.DGNST_TAG_SET;
3257
                                } else {
3258
                                        psEI.stype = DGNFileHeader.DGNST_CORE;
3259
                                }
3260
                        } else if (elemento.type == DGNFileHeader.DGNT_TCB) {
3261
                                DGNElemCore psTCB = DGNParseTCB(psDGN);
3262

    
3263
                                //DGNFreeElement( psDGN, psTCB );
3264
                                psEI.stype = DGNFileHeader.DGNST_TCB;
3265
                        } else {
3266
                                psEI.stype = DGNFileHeader.DGNST_CORE;
3267
                        }
3268

    
3269
                        //DGNInfo tempo = new DGNInfo();
3270
                        double[] anRegion;
3271

    
3272
                        if (((psEI.flags & DGNFileHeader.DGNEIF_DELETED) == FALSE) &
3273
                                        ((psEI.flags & DGNFileHeader.DGNEIF_COMPLEX) == FALSE) &
3274
                                        ((anRegion = DGNGetRawExtents(psDGN, null, elemento)) != null)) {
3275
                                //        #ifdef notdef
3276
                                // System.out.println( "element_count"+psDGN.element_count+"anRegion[]"+("xmin"+anRegion[0])+"xmax"+anRegion[1]+"ymin"+anRegion[3]+"ymax"+anRegion[4]+ 2147483648.0 );
3277
                                //#endif
3278

    
3279
                                /*        double aux=0;
3280
                                   if (anRegion[0]>anRegion[3]){
3281
                                           aux=anRegion[3];
3282
                                           anRegion[3]=anRegion[0];
3283
                                           anRegion[0]=anRegion[3];
3284
                                   }
3285
                                   if (anRegion[1]>anRegion[4]){
3286
                                                                           aux=anRegion[4];
3287
                                                                           anRegion[4]=anRegion[1];
3288
                                                                           anRegion[1]=anRegion[4];
3289
                                                                   }*/
3290
                                if (psDGN.got_bounds != FALSE) {
3291
                                        psDGN.min_x = Math.min(psDGN.min_x, anRegion[0]);
3292
                                        psDGN.min_y = Math.min(psDGN.min_y, anRegion[1]);
3293
                                        psDGN.min_z = Math.min(psDGN.min_z, anRegion[2]);
3294
                                        psDGN.max_x = Math.max(psDGN.max_x, anRegion[3]);
3295
                                        psDGN.max_y = Math.max(psDGN.max_y, anRegion[4]);
3296
                                        psDGN.max_z = Math.max(psDGN.max_z, anRegion[5]);
3297
                                } else {
3298
                                        psDGN.min_x = anRegion[0];
3299
                                        psDGN.min_y = anRegion[1];
3300
                                        psDGN.min_z = anRegion[2];
3301
                                        psDGN.max_x = anRegion[3];
3302
                                        psDGN.max_y = anRegion[4];
3303
                                        psDGN.max_z = anRegion[5];
3304

    
3305
                                        //memcpy( (psDGN.min_x), anRegion, sizeof(long) * 6 );
3306
                                        psDGN.got_bounds = TRUE;
3307
                                }
3308

    
3309
                                // System.out.println("xmin"+anRegion[0]+"xmax"+anRegion[3]+"ymin"+anRegion[1]+"ymax"+anRegion[4]+ "      "+2147483648.0 );
3310
                        }
3311

    
3312
                        psDGN.element_count++;
3313

    
3314
                        //nLastOffset = VSIFTell( psDGN.fp );
3315
                        nLastOffset = bb.position(); // psDGN.ftall;
3316
                }
3317

    
3318
                //DGNRewind( psDGN );
3319
                psDGN.max_element_count = nMaxElements;
3320
        }
3321

    
3322
        /**
3323
         * Devuelve el rect?ngulo que representa el extent del elemento.
3324
         *
3325
         * @param psDGN informaci?n del DGN.
3326
         * @param psElement elemento.
3327
         * @param psMin punto m?nimo.
3328
         * @param psMax punto m?ximo.
3329
         *
3330
         * @return Entero para comprobar si se ha calculado correctamente.
3331
         */
3332
        private int DGNGetElementExtents(DGNInfo psDGN, DGNElemCore psElement,
3333
                DGNPoint psMin, DGNPoint psMax) {
3334
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3335
                long[] anMin = new long[3];
3336
                long[] anMax = new long[3];
3337
                DGNInfo tempo = new DGNInfo();
3338
                double[] bResult;
3339

    
3340
                /* -------------------------------------------------------------------- */
3341
                /*      Get the extents if we have raw data in the element, or          */
3342
                /*      loaded in the file buffer.                                      */
3343
                /* -------------------------------------------------------------------- */
3344
                if (psElement.raw_data != null) {
3345
                        bResult = DGNGetRawExtents(psDGN, psElement.raw_data, psElement);
3346
                } else {
3347
                        if (psElement.element_id == (psDGN.next_element_id - 1)) {
3348
                                bResult = DGNGetRawExtents(psDGN, psDGN.abyElem, psElement);
3349
                        } else {
3350
                                /*CPLError(CE_Warning, CPLE_AppDefined,
3351
                                   "DGNGetElementExtents() fails because the requested element\n"
3352
                                   " does not have raw data available." );
3353
                                 */
3354
                                return FALSE;
3355
                        }
3356
                }
3357

    
3358
                if (bResult == null) {
3359
                        return FALSE;
3360
                }
3361

    
3362
                /* -------------------------------------------------------------------- */
3363
                /*      Transform to user coordinate system and return.  The offset     */
3364
                /*      is to convert from "binary offset" form to twos complement.     */
3365
                /* -------------------------------------------------------------------- */
3366
                psMin.x = tempo.min_x - 2147483648.0;
3367
                psMin.y = tempo.min_y - 2147483648.0;
3368
                psMin.z = tempo.min_z - 2147483648.0;
3369

    
3370
                psMax.x = tempo.max_x - 2147483648.0;
3371
                psMax.y = tempo.max_y - 2147483648.0;
3372
                psMax.z = tempo.max_z - 2147483648.0;
3373

    
3374
                DGNTransformPoint(psDGN, psMin);
3375
                DGNTransformPoint(psDGN, psMax);
3376

    
3377
                return TRUE;
3378
        }
3379

    
3380
        /**
3381
         * Devuelve los ?ndices de los elementos del DGN.
3382
         *
3383
         * @param psDGN Informaci?n del DGN.
3384
         * @param pnElementCount N?mero de elementos.
3385
         *
3386
         * @return ?ndices.
3387
         */
3388
        private DGNElementInfo[] DGNGetElementIndex(DGNInfo psDGN,
3389
                int[] pnElementCount) {
3390
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3391
                DGNBuildIndex(psDGN);
3392

    
3393
                if (pnElementCount[0] != -1) {
3394
                        pnElementCount[0] = psDGN.element_count;
3395
                }
3396

    
3397
                return psDGN.element_index;
3398
        }
3399

    
3400
        /************************************************************************/
3401
        /*                           DGNLookupColor()                           */
3402
        /************************************************************************/
3403

    
3404
        /**
3405
         * Translate color index into RGB values. If no color table has yet been
3406
         * encountered in the file a hard-coded "default" color table will be
3407
         * used.  This seems to be what Microstation uses as a color table when
3408
         * there isn't one in a DGN file but I am not absolutely convinced it is
3409
         * appropriate.
3410
         *
3411
         * @param color_index the color index to lookup.
3412
         *
3413
         * @return TRUE on success or FALSE on failure.  May fail if color_index is
3414
         *                    out of range.
3415
         */
3416
        public Color DGNLookupColor(int color_index) {
3417
                int r;
3418
                int g;
3419
                int b;
3420

    
3421
                if ((color_index < 0) || (color_index > 255)) {
3422
                        return null;
3423
                }
3424

    
3425
                if (info.got_color_table == 0) {
3426
                        r = abyDefaultPCT[color_index][0];
3427
                        g = abyDefaultPCT[color_index][1];
3428
                        b = abyDefaultPCT[color_index][2];
3429
                } else {
3430
                        r = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][0]);
3431
                        g = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][1]);
3432
                        b = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][2]);
3433

    
3434
                        if ((r == 255) && (g == 255) && (b == 255)) {
3435
                                r = g = b = 0; // El color blanco lo devolvemos como negro.
3436
                        }
3437
                }
3438

    
3439
                return new Color(r, g, b, 150);
3440
        }
3441

    
3442
        /************************************************************************/
3443
        /*                        DGNGetShapeFillInfo()                         */
3444
        /************************************************************************/
3445

    
3446
        /**
3447
         * Fetch fill color for a shape. This method will check for a 0x0041 user
3448
         * attribute linkaged with fill color information for the element.  If
3449
         * found the function returns TRUE, and places the fill color in pnColor,
3450
         * otherwise FALSE is returned and pnColor is not updated.
3451
         *
3452
         * @param psElem the element.
3453
         *
3454
         * @return index of color on success or -1 on failure.
3455
         */
3456
        public int DGNGetShapeFillInfo(DGNElemCore psElem) {
3457
                int iLink;
3458
                int color_index = -1;
3459

    
3460
                for (iLink = 0; true; iLink++) {
3461
                        int[] nLinkType = new int[1];
3462
                        int[] nEntityNum = new int[1];
3463
                        int[] nMSLink = new int[1];
3464
                        int[] nLinkSize = new int[1];
3465
                        int i;
3466
                        nEntityNum[0] = 0;
3467
                        nMSLink[0] = 0;
3468

    
3469
                        byte[] pabyData;
3470

    
3471
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3472
                                        nEntityNum, nMSLink, nLinkSize);
3473

    
3474
                        if (pabyData == null) {
3475
                                return -1;
3476
                        }
3477

    
3478
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_SHAPE_FILL) &&
3479
                                        (nLinkSize[0] >= 7)) {
3480
                                color_index = ByteUtils.getUnsigned(pabyData[8]);
3481

    
3482
                                break;
3483
                        }
3484
                }
3485

    
3486
                return color_index;
3487
        }
3488

    
3489
        /************************************************************************/
3490
        /*                        DGNGetAssocID()                               */
3491
        /************************************************************************/
3492

    
3493
        /**
3494
         * Fetch association id for an element. This method will check if an
3495
         * element has an association id, and if so returns it, otherwise
3496
         * returning -1.  Association ids are kept as a user attribute linkage
3497
         * where present.
3498
         *
3499
         * @param psElem the element.
3500
         *
3501
         * @return The id or -1 on failure.
3502
         */
3503
        int DGNGetAssocID(DGNElemCore psElem) {
3504
                int iLink;
3505

    
3506
                for (iLink = 0; true; iLink++) {
3507
                        int[] nLinkType = new int[1];
3508
                        int[] nEntityNum = new int[1];
3509
                        int[] nMSLink = new int[1];
3510
                        int[] nLinkSize = new int[1];
3511
                        int i;
3512
                        nEntityNum[0] = 0;
3513
                        nMSLink[0] = 0;
3514

    
3515
                        byte[] pabyData;
3516

    
3517
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3518
                                        nEntityNum, nMSLink, nLinkSize);
3519

    
3520
                        if (pabyData == null) {
3521
                                return -1;
3522
                        }
3523

    
3524
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_ASSOC_ID) &&
3525
                                        (nLinkSize[0] >= 8)) {
3526
                                return ByteUtils.getUnsigned(pabyData[4]) +
3527
                                (ByteUtils.getUnsigned(pabyData[5]) * 256) +
3528
                                (ByteUtils.getUnsigned(pabyData[6]) * 256 * 256) +
3529
                                (ByteUtils.getUnsigned(pabyData[7]) * 256 * 256 * 256);
3530
                        }
3531
                }
3532
        }
3533
}