Statistics
| Revision:

svn-gvsig-desktop / tags / v10_RC2c / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dgn / DGNReader.java @ 8745

History | View | Annotate | Download (97.7 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.ByteBuffer;
55
import java.nio.ByteOrder;
56
import java.nio.MappedByteBuffer;
57
import java.nio.channels.FileChannel;
58

    
59

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
421
                bb.rewind();
422
        }
423

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

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

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

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

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

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

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

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

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

    
497
                return TRUE;
498
        }
499

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

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

    
525
                        FileChannel fc = fin.getChannel();
526

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

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

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

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

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

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

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

    
560
                return info;
561
        }
562

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

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

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

    
591
                return TRUE;
592
        }
593

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

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

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

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

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

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

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

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

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

    
661
                        return FALSE;
662
                }
663

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

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

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

    
676
                return TRUE;
677
        }
678

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

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

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

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

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

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

    
709
                info.sf_converted_to_uor = TRUE;
710
        }
711

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

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

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

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

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

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

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

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

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

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

    
784
                return elemento;
785
        }
786

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
901
                                break;
902

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

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

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

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

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

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

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

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

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

    
1006
                        break;
1007

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

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

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

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

    
1050
                                elemento = psCell;
1051
                        }
1052

    
1053
                        break;
1054

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

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

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

    
1097
                        break;
1098

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

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

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

    
1118
                                        return null;
1119
                                }
1120

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

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

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

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

    
1143
                                elemento = psLine;
1144
                        }
1145

    
1146
                        break;
1147

    
1148
                        case DGNFileHeader.DGNT_GROUP_DATA:
1149

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1230
                        break;
1231

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

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

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

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

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

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

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

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

    
1279
                                psEllipse.secondary_axis *= info.scale;
1280

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

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

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

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

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

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

    
1321
                        break;
1322

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

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

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

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

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

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

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

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

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

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

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

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

    
1387
                                elemento = psText;
1388
                        }
1389

    
1390
                        break;
1391

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

    
1397
                                break;
1398

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

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

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

    
1413
                        break;
1414

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

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

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

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

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

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

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

    
1458
                                elemento = psTag;
1459
                        }
1460

    
1461
                        break;
1462

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

    
1477
                        break;
1478
                }
1479

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

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

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

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

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

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

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

    
1521
                return DGNParseIEEE(temp);
1522
        }
1523

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

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

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

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

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

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

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

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

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

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

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

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

    
1613
                f[0] = 0;
1614

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

    
1617
                return value;
1618
        }
1619

    
1620
        /**
1621
         * Cambia el double a IEEDouble.
1622
         *
1623
         * @param dbl double de entrada.
1624
         */
1625
        /**
1626
         * Cambia el double a IEEDouble.
1627
         *
1628
         * @param dbl double de entrada.
1629
         */
1630
        private double DGN2IEEEDouble(double dbl) {
1631
                int tempInt = (int) Double.doubleToLongBits(dbl);
1632
        int low = (tempInt & 0xffff0000) >>> 16; // >>>: Right shift without
1633
        // sign extension
1634
        int high = (tempInt & 0x0000ffff) << 16;
1635
        tempInt = high | low;
1636
        int s = ((tempInt >> 31) == 0) ? 1 : -1;
1637
        int e = ((tempInt >> 23) & 0xff);
1638
        int m = (tempInt & 0x7fffff) | 0x800000;
1639
        return ((s * m * 2 * Math.pow(2, e - 128 - 25)));
1640
        }
1641

    
1642
        /**
1643
         * DOCUMENT ME!
1644
         *
1645
         * @param dbl DOCUMENT ME!
1646
         */
1647
        private void IEEE2DGNDouble(double dbl) {
1648
                double64 dt = new double64();
1649

    
1650
                dt.hi = 0;
1651
                dt.lo = 0;
1652

    
1653
                long sign;
1654
                long exponent;
1655
                long rndbits;
1656
                byte[] srclo = new byte[4];
1657
                byte[] srchi = new byte[4];
1658
                byte[] destlo = new byte[4];
1659
                byte[] desthi = new byte[4];
1660
                byte[] src = new byte[8];
1661
                byte[] dest = new byte[8];
1662

    
1663
                for (int i = 0; i < 8; i++) {
1664
                        src[i] = '0';
1665
                        dest[i] = '0';
1666
                }
1667

    
1668
                int[] fin = new int[1];
1669

    
1670
                if (LSB == TRUE) {
1671
                        fin[0] = 0;
1672
                        ByteUtils.doubleToBytes(dbl, src, fin);
1673
                        dest[0] = src[4];
1674
                        dest[1] = src[5];
1675
                        dest[2] = src[6];
1676
                        dest[3] = src[7];
1677
                        dest[4] = src[0];
1678
                        dest[5] = src[1];
1679
                        dest[6] = src[2];
1680
                        dest[7] = src[3];
1681
                } else {
1682
                        //memcpy( &dt, dbl, 8 );
1683
                }
1684

    
1685
                sign = dt.hi & 0x80000000;
1686
                exponent = dt.hi >> 20;
1687
                exponent = exponent & 0x000007ff;
1688

    
1689
                /* -------------------------------------------------------------------- */
1690
                /*        An exponent of zero means a zero value.                                */
1691
                /* -------------------------------------------------------------------- */
1692
                if (exponent != FALSE) {
1693
                        exponent = exponent - 1023 + 129;
1694
                }
1695

    
1696
                /* -------------------------------------------------------------------- */
1697
                /*        In the case of overflow, return the largest number we can        */
1698
                /* -------------------------------------------------------------------- */
1699
                if (exponent > 255) {
1700
                        fin[0] = 0;
1701
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1702

    
1703
                        if (sign != FALSE) {
1704
                                dest[1] = 0xf;
1705
                        } else {
1706
                                dest[1] = 0x7f;
1707
                        }
1708

    
1709
                        dest[0] = 0xf;
1710
                        dest[2] = 0xf;
1711
                        dest[3] = 0xf;
1712
                        dest[4] = 0xf;
1713
                        dest[5] = 0xf;
1714
                        dest[6] = 0xf;
1715
                        dest[7] = 0xf;
1716

    
1717
                        return;
1718
                }
1719
                /* -------------------------------------------------------------------- */
1720
                /*        In the case of of underflow return zero                                */
1721
                /* -------------------------------------------------------------------- */
1722
                else if ((exponent < 0) || ((exponent == 0) && (sign == 0))) {
1723
                        fin[0] = 0;
1724
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1725
                        dest[0] = 0x00;
1726
                        dest[1] = 0x00;
1727
                        dest[2] = 0x00;
1728
                        dest[3] = 0x00;
1729
                        dest[4] = 0x00;
1730
                        dest[5] = 0x00;
1731
                        dest[6] = 0x00;
1732
                        dest[7] = 0x00;
1733

    
1734
                        return;
1735
                } else {
1736
                        /* -------------------------------------------------------------------- */
1737
                        /*            Shift the fraction 3 bits left and set the exponent and sign*/
1738
                        /* -------------------------------------------------------------------- */
1739
                        System.arraycopy(dest, 0, destlo, 0, 4);
1740
                        fin[0] = 0;
1741
                        dt.lo = ByteUtils.bytesToLong(destlo, fin);
1742
                        System.arraycopy(dest, 4, desthi, 0, 4);
1743
                        fin[0] = 0;
1744
                        dt.hi = ByteUtils.bytesToLong(desthi, fin);
1745

    
1746
                        dt.hi = dt.hi << 3;
1747
                        dt.hi = dt.hi | (dt.lo >> 29);
1748
                        dt.hi = dt.hi & 0x007fffff;
1749
                        dt.hi = dt.hi | (exponent << 23) | sign;
1750

    
1751
                        dt.lo = dt.lo << 3;
1752
                }
1753

    
1754
                /* -------------------------------------------------------------------- */
1755
                /*        Convert the double back to VAX format                                */
1756
                /* -------------------------------------------------------------------- */
1757
                fin[0] = 0;
1758

    
1759
                ByteUtils.longToBytes(dt.lo, srclo, fin);
1760

    
1761
                fin[0] = 0;
1762
                ByteUtils.longToBytes(dt.hi, srchi, fin);
1763

    
1764
                if (LSB == TRUE) {
1765
                        dest[2] = srclo[0];
1766
                        dest[3] = srclo[1];
1767
                        dest[0] = srclo[2];
1768
                        dest[1] = srclo[3];
1769
                        dest[6] = srchi[0];
1770
                        dest[7] = srchi[1];
1771
                        dest[4] = srchi[2];
1772
                        dest[5] = srchi[3];
1773
                } else {
1774
                        dest[1] = srclo[0];
1775
                        dest[0] = srclo[1];
1776
                        dest[3] = srclo[2];
1777
                        dest[2] = srclo[3];
1778
                        dest[5] = srchi[0];
1779
                        dest[4] = srchi[1];
1780
                        dest[7] = srchi[2];
1781
                        dest[6] = srchi[3];
1782
                }
1783

    
1784
                fin[0] = 0;
1785
                dbl = ByteUtils.bytesToDouble(dest, fin);
1786

    
1787
                ////System.out.println("dbl=  " + dbl);
1788
        }
1789

    
1790
        /************************************************************************/
1791
        /*                       DGNElemTypeHasDispHdr()                        */
1792
        /************************************************************************/
1793

    
1794
        /**
1795
         * Does element type have display header.
1796
         *
1797
         * @param nElemType element type (0-63) to test.
1798
         *
1799
         * @return TRUE if elements of passed in type have a display header after
1800
         *                    the core element header, or FALSE otherwise.
1801
         */
1802
        private int DGNElemTypeHasDispHdr(int nElemType) {
1803
                switch (nElemType) {
1804
                        case 0:
1805
                        case DGNFileHeader.DGNT_TCB:
1806
                        case DGNFileHeader.DGNT_CELL_LIBRARY:
1807
                        case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
1808
                        case 32:
1809
                        case 44:
1810
                        case 48:
1811
                        case 49:
1812
                        case 50:
1813
                        case 51:
1814
                        case 57:
1815
                        case 63:
1816
                                return FALSE;
1817

    
1818
                        default:
1819
                                return TRUE;
1820
                }
1821
        }
1822

    
1823
        /**
1824
         * DOCUMENT ME!
1825
         *
1826
         * @param info DOCUMENT ME!
1827
         * @param elemento DOCUMENT ME!
1828
         *
1829
         * @return DOCUMENT ME!
1830
         */
1831
        private int DGNParseCore(DGNInfo info, DGNElemCore elemento) {
1832
                byte[] psData = info.abyElem; //0
1833

    
1834
                elemento.level = psData[0] & (byte) 0x3f;
1835
                elemento.complex = psData[0] & (byte) 0x80;
1836
                elemento.deleted = psData[1] & (byte) 0x80;
1837
                elemento.type = psData[1] & (byte) 0x7f;
1838

    
1839
                if ((info.nElemBytes >= 36) &&
1840
                                (DGNElemTypeHasDispHdr(elemento.type) == TRUE)) {
1841
                        // (elemento.type != DGNFileHeader.DGNT_CELL_LIBRARY)) {
1842
                        elemento.graphic_group = psData[28] + (psData[29] * 256);
1843
                        elemento.properties = psData[32] + (psData[33] * 256);
1844

    
1845
                        elemento.style = psData[34] & (byte) 0x7;
1846
                        elemento.weight = (psData[34] & (byte) 0xf8) >> 3;
1847

    
1848
                        byte aux = psData[35];
1849

    
1850
                        // System.out.println("aux = " + aux);
1851
                        elemento.color = ByteUtils.getUnsigned(aux);
1852

    
1853
                        // elemento.color = psData[35];
1854
                        // System.out.println("elemento.color = " + elemento.color);
1855
                } else {
1856
                        elemento.graphic_group = 0;
1857
                        elemento.properties = 0;
1858
                        elemento.style = 0;
1859
                        elemento.weight = 0;
1860
                        elemento.color = 0;
1861
                }
1862

    
1863
                if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
1864
                        // if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) == TRUE) {
1865
                        int nAttIndex;
1866

    
1867
                        nAttIndex = ByteUtils.getUnsigned(psData[30]) +
1868
                                (ByteUtils.getUnsigned(psData[31]) * 256);
1869

    
1870
                        int numBytes = info.nElemBytes - (nAttIndex * 2) - 32;
1871

    
1872
                        if ((numBytes > 0)) {
1873
                                // Como m?ximo guardamos 10 bytes (Total, lo queremos para el color....
1874
                                // if (numBytes > 10) numBytes = 10;
1875
                                elemento.attr_bytes = numBytes;
1876

    
1877
                                elemento.attr_data = new byte[elemento.attr_bytes];
1878

    
1879
                                // System.out.println("nAttIndex = " + nAttIndex + " numBytes = " + numBytes );
1880
                                System.arraycopy(psData, (nAttIndex * 2) + 32,
1881
                                        elemento.attr_data, 0, elemento.attr_bytes);
1882
                        }
1883
                }
1884

    
1885
                return TRUE;
1886
        }
1887

    
1888
        /**
1889
         * DOCUMENT ME!
1890
         *
1891
         * @param rad50 DOCUMENT ME!
1892
         * @param str DOCUMENT ME!
1893
         */
1894
        private void DGNRad50ToAscii(int rad50, byte[] str) {
1895
                byte cTimes;
1896
                int value;
1897
                int temp;
1898
                byte ch = '\0';
1899
                int i = 0;
1900

    
1901
                while (rad50 > 0) {
1902
                        value = rad50;
1903
                        cTimes = 0;
1904

    
1905
                        while (value >= 40) {
1906
                                value /= 40;
1907
                                cTimes++;
1908
                        }
1909

    
1910
                        byte[] abc = {
1911
                                        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
1912
                                        'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
1913
                                        'Y', 'Z'
1914
                                };
1915
                        byte[] num = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
1916

    
1917
                        /* Map 0..39 to ASCII */
1918
                        if (value == 0) {
1919
                                ch = ' '; /* space */
1920
                        } else if ((value >= 1) && (value <= 26)) {
1921
                                ch = abc[value - 1]; /* printable alpha A..Z */
1922
                        } else if (value == 27) {
1923
                                ch = '$'; /* dollar */
1924
                        } else if (value == 28) {
1925
                                ch = '.'; /* period */
1926
                        } else if (value == 29) {
1927
                                ch = ' '; /* unused char, emit a space instead */
1928
                        } else if ((value >= 30) && (value <= 39)) {
1929
                                ch = num[value - 30]; /* digit 0..9 */
1930
                        }
1931

    
1932
                        str[i] = ch;
1933
                        i++;
1934

    
1935
                        temp = 1;
1936

    
1937
                        while (cTimes-- > 0)
1938
                                temp *= 40;
1939

    
1940
                        rad50 -= (value * temp);
1941
                }
1942

    
1943
                /* Do zero-terminate */
1944
                str[i] = '\0';
1945
        }
1946

    
1947
        /**
1948
         * Transforma el punto.
1949
         *
1950
         * @param info Informaci?n del DGN.
1951
         * @param psPoint Punto.
1952
         */
1953
        private void DGNTransformPoint(DGNInfo info, DGNPoint psPoint) {
1954
                psPoint.x = (psPoint.x * info.scale) - info.origin_x;
1955

    
1956
                // System.out.println("info.scale= "+info.scale+"info.origin_x= "+info.origin_x);
1957
                psPoint.y = (psPoint.y * info.scale) - info.origin_y;
1958

    
1959
                // System.out.println("info.origin_y= "+info.origin_y);
1960
                psPoint.z = (psPoint.z * info.scale) - info.origin_z;
1961

    
1962
                // System.out.println("x= "+psPoint.x+"y= "+psPoint.y);
1963
        }
1964

    
1965
        /**
1966
         * DOCUMENT ME!
1967
         *
1968
         * @param psDGN DOCUMENT ME!
1969
         *
1970
         * @return DOCUMENT ME!
1971
         */
1972
        private DGNElemCore DGNParseColorTable(DGNInfo psDGN) {
1973
                DGNElemColorTable psColorTable = new DGNElemColorTable();
1974

    
1975
                psColorTable.stype = DGNFileHeader.DGNST_COLORTABLE;
1976

    
1977
                DGNParseCore(psDGN, psColorTable);
1978

    
1979
                psColorTable.screen_flag = ByteUtils.byteToUnsignedInt(psDGN.abyElem[36]) +
1980
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[37]) * 256);
1981

    
1982
                int[] fin = new int[1];
1983
                fin[0] = 0;
1984

    
1985
                byte[] temp = new byte[3];
1986
                System.arraycopy(psDGN.abyElem, 38, temp, 0, 3);
1987
                psColorTable.color_info[255] = temp;
1988

    
1989
                byte[] temp2 = new byte[765];
1990
                System.arraycopy(psDGN.abyElem, 41, temp2, 0, 765);
1991

    
1992
                int k = 0;
1993

    
1994
                for (int i = 0; i < 255; i++) {
1995
                        for (int j = 0; j < 3; j++) {
1996
                                psColorTable.color_info[i][j] = temp2[k];
1997
                                k++;
1998
                        }
1999

    
2000
                        // System.err.println("Color " + psColorTable.color_info[i][0] + " " + 
2001
                        //                psColorTable.color_info[i][1] + " " + psColorTable.color_info[i][2]);
2002
                }
2003

    
2004
                if (psDGN.got_color_table == FALSE) {
2005
                        psDGN.color_table = psColorTable.color_info;
2006

    
2007
                        psDGN.got_color_table = 1;
2008
                }
2009

    
2010
                return psColorTable;
2011
        }
2012

    
2013
        /**
2014
         * DOCUMENT ME!
2015
         *
2016
         * @param psDGN DOCUMENT ME!
2017
         *
2018
         * @return DOCUMENT ME!
2019
         */
2020
        private DGNElemCore DGNParseTCB(DGNInfo psDGN) {
2021
                DGNElemTCB psTCB = new DGNElemTCB();
2022
                int iView;
2023
                int[] fin = new int[1];
2024
                psTCB.stype = DGNFileHeader.DGNST_TCB;
2025
                DGNParseCore(psDGN, psTCB);
2026

    
2027
                if ((psDGN.abyElem[1214] & (byte) 0x40) != FALSE) {
2028
                        psTCB.dimension = 3;
2029
                } else {
2030
                        psTCB.dimension = 2;
2031
                }
2032

    
2033
                // psTCB.dimension = 3;
2034
                fin[0] = 0;
2035

    
2036
                byte[] temp1 = new byte[8];
2037
                System.arraycopy(psDGN.abyElem, 1112, temp1, 0, 4);
2038
                psTCB.subunits_per_master = DGN_INT32(temp1);
2039

    
2040
                psTCB.master_units[0] = (char) (psDGN.abyElem[1120]);
2041
                psTCB.master_units[1] = (char) (psDGN.abyElem[1121]);
2042
                psTCB.master_units[2] = '\0';
2043

    
2044
                System.arraycopy(psDGN.abyElem, 1116, temp1, 0, 4);
2045
                psTCB.uor_per_subunit = DGN_INT32(temp1);
2046

    
2047
                psTCB.sub_units[0] = (char) (psDGN.abyElem[1122]);
2048
                psTCB.sub_units[1] = (char) (psDGN.abyElem[1123]);
2049
                psTCB.sub_units[2] = '\0';
2050

    
2051
                /* Get global origin */
2052
                ByteBuffer buffer = ByteBuffer.wrap(psDGN.abyElem);
2053
                buffer.order(ByteOrder.LITTLE_ENDIAN);
2054
                psTCB.origin_x = buffer.getDouble(1240);
2055
                psTCB.origin_y = buffer.getDouble(1248);
2056
                psTCB.origin_z = buffer.getDouble(1256);
2057

    
2058
                /* Transform to IEEE */
2059
                psTCB.origin_x = DGN2IEEEDouble(psTCB.origin_x);
2060
                psTCB.origin_y = DGN2IEEEDouble(psTCB.origin_y);
2061
                psTCB.origin_z = DGN2IEEEDouble(psTCB.origin_z);
2062

    
2063
                /* Convert from UORs to master units. */
2064
                if ((psTCB.uor_per_subunit != 0) && (psTCB.subunits_per_master != 0)) {
2065
                        psTCB.origin_x = psTCB.origin_x / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2066
                        psTCB.origin_y = psTCB.origin_y / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2067
                        psTCB.origin_z = psTCB.origin_z / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2068
                }
2069

    
2070
                // psDGN.dimension = psTCB.dimension;
2071
                if (psDGN.got_tcb == FALSE) {
2072
                        psDGN.got_tcb = TRUE;
2073

    
2074
                        psDGN.origin_x = psTCB.origin_x;
2075
                    psDGN.origin_y = psTCB.origin_y;
2076
                    psDGN.origin_z = psTCB.origin_z; 
2077
                        if ((psTCB.uor_per_subunit != 0) &&
2078
                                        (psTCB.subunits_per_master != 0)) {
2079
                                psDGN.scale = 1.0 / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
2080
                        }
2081
                }
2082

    
2083
                /* System.err.println("Ojo: HAY TCB!!");
2084
                   System.out.println("Datos del TCB: " + psTCB.origin_x + " " + psTCB.origin_y);
2085
                   System.out.println("psTCB.uor_per_subunit: " + psTCB.uor_per_subunit + " psTCB.subunits_per_master: " + psTCB.subunits_per_master);
2086
                   // System.out.println("psTCB.master_units = " + new String(psTCB.master_units) +
2087
                   //                 " psTCB.sub_units = " + new String(psTCB.sub_units));
2088
                   System.out.println("psTCB.origen = " + psTCB.origin_x + " " + psTCB.origin_y);
2089
                   System.out.println("psDGN.scale = " + psDGN.scale);
2090
                   System.out.println("psDGN.origen = " + psDGN.origin_x + " " + psDGN.origin_y);
2091
                   System.out.println("psDGN.dimension = " + psDGN.dimension); */
2092
                /* Collect views */
2093
                for (iView = 0; iView < 8; iView++) {
2094
                        byte[] pabyRawView = new byte[psDGN.abyElem.length];
2095
                        fin[0] = 0;
2096
                        System.arraycopy(psDGN.abyElem, (46 + (iView * 118)), pabyRawView,
2097
                                0, psDGN.abyElem.length - (46 + (iView * 118)));
2098

    
2099
                        psTCB.views[iView] = new DGNViewInfo();
2100
                        psTCB.views[iView].flags = ByteUtils.byteToUnsignedInt(pabyRawView[0]) +
2101
                                (ByteUtils.byteToUnsignedInt(pabyRawView[1]) * 256);
2102

    
2103
                        byte[] temp2 = new byte[4];
2104
                        int f = 0;
2105

    
2106
                        for (int j = 0; j < 8; j++) {
2107
                                System.arraycopy(pabyRawView, j + 2, temp2, 0, 1);
2108
                                fin[0] = 0;
2109
                                psTCB.views[iView].levels[f] = temp2[0];
2110
                                f++;
2111
                        }
2112

    
2113
                        psTCB.views[iView].origin = new DGNPoint();
2114
                        System.arraycopy(pabyRawView, 10, temp1, 0, 4);
2115
                        psTCB.views[iView].origin.x = DGN_INT32(temp1);
2116

    
2117
                        System.arraycopy(pabyRawView, 14, temp1, 0, 4);
2118
                        psTCB.views[iView].origin.y = DGN_INT32(temp1);
2119
                        System.arraycopy(pabyRawView, 18, temp1, 0, 4);
2120
                        psTCB.views[iView].origin.z = DGN_INT32(temp1);
2121
                        DGNTransformPoint(psDGN, (psTCB.views[iView].origin));
2122

    
2123
                        psTCB.views[iView].delta = new DGNPoint();
2124
                        System.arraycopy(pabyRawView, 22, temp1, 0, 4);
2125
                        psTCB.views[iView].delta.x = DGN_INT32(temp1);
2126
                        System.arraycopy(pabyRawView, 26, temp1, 0, 4);
2127
                        psTCB.views[iView].delta.y = DGN_INT32(temp1);
2128
                        System.arraycopy(pabyRawView, 30, temp1, 0, 4);
2129
                        psTCB.views[iView].delta.z = DGN_INT32(temp1);
2130

    
2131
                        psTCB.views[iView].delta.x *= psDGN.scale;
2132
                        psTCB.views[iView].delta.y *= psDGN.scale;
2133
                        psTCB.views[iView].delta.z *= psDGN.scale;
2134

    
2135
                        //memcpy( psTCB.views[iView].transmatrx, pabyRawView + 34, sizeof(double) * 9 );
2136
                        psTCB.views[iView].transmatrx = new double[9];
2137

    
2138
                        for (int k = 0; k < 9; k++) {
2139
                                System.arraycopy(pabyRawView, (34 + (8 * k)), temp1, 0, 8);
2140

    
2141
                                //fin[0]=0;
2142
                                //double d=ByteUtils.bytesToDouble(temp1,fin);
2143
                                fin[0] = 0;
2144
                                psTCB.views[iView].transmatrx[k] = DGNParseIEEE(temp1);
2145

    
2146
                                //nuevo m?todo
2147
                        }
2148

    
2149
                        System.arraycopy(pabyRawView, 106, temp1, 0, 8);
2150
                        fin[0] = 0;
2151
                        psTCB.views[iView].conversion = ByteUtils.bytesToLong(temp1, fin);
2152
                        fin[0] = 0;
2153
                        psTCB.views[iView].conversion = ByteUtils.bytesToDouble(temp1, fin);
2154

    
2155
                        //memcpy( (psTCB.views[iView].conversion), pabyRawView + 106, sizeof(double) );
2156
                        DGNParseIEEE(psTCB.views[iView].conversion);
2157
                        System.arraycopy(pabyRawView, 114, temp1, 0, 8);
2158
                        psTCB.views[iView].activez = DGN_INT32(temp1);
2159
                }
2160

    
2161
                // DGNDumpElement(psDGN, psTCB,"");
2162
                return psTCB;
2163
        }
2164

    
2165
        /**
2166
         * Cambia un entero a LitterIndian.
2167
         *
2168
         * @param x Entero de entrada.
2169
         *
2170
         * @return Entero de salida.
2171
         */
2172
        private int CPL_LSBWORD32(int x) {
2173
                return ((int) ((((int) (x) & (int) 0x000000ff) << 24) |
2174
                (((int) (x) & (int) 0x0000ff00) << 8) |
2175
                (((int) (x) & (int) 0x00ff0000) >> 8) |
2176
                (((int) (x) & (int) 0xff000000) >> 24)));
2177
        }
2178

    
2179
        /**
2180
         * Cambia el vector de char de entrada en el caso de ser null por el
2181
         * caracter vacio.
2182
         *
2183
         * @param pszString Vector de char.
2184
         *
2185
         * @return Vector de char.
2186
         */
2187
        private char[] CPLStrdup(char[] pszString) {
2188
                char[] pszReturn;
2189

    
2190
                if (pszString == null) {
2191
                        pszString[0] = ' ';
2192
                }
2193

    
2194
                pszReturn = new char[pszString.length];
2195

    
2196
                //pszReturn = VSIStrdup( pszString );
2197
                pszReturn = pszString;
2198

    
2199
                if (pszReturn == null) {
2200
                        System.out.println("error");
2201

    
2202
                        /*
2203
                           CPLError( CE_Fatal, CPLE_OutOfMemory,
2204
                                                             "CPLStrdup(): Out of memory allocating %d bytes.\n",
2205
                                                             strlen(pszString) );*/
2206
                }
2207

    
2208
                return (pszReturn);
2209
        }
2210

    
2211
        /**
2212
         * DOCUMENT ME!
2213
         *
2214
         * @param psDGN DOCUMENT ME!
2215
         *
2216
         * @return DOCUMENT ME!
2217
         */
2218
        private DGNElemCore DGNParseTagSet(DGNInfo psDGN) {
2219
                //DGNElemCore psElement;
2220
                DGNElemTagSet psTagSet = new DGNElemTagSet();
2221
                int nDataOffset;
2222
                int iTag;
2223

    
2224
                //psTagSet = (DGNElemTagSet *) CPLCalloc(sizeof(DGNElemTagSet),1);
2225
                //psElement = (DGNElemCore *) psTagSet;
2226
                psTagSet.stype = DGNFileHeader.DGNST_TAG_SET;
2227

    
2228
                DGNParseCore(psDGN, psTagSet);
2229

    
2230
                /* -------------------------------------------------------------------- */
2231
                /*      Parse the overall information.                                  */
2232
                /* -------------------------------------------------------------------- */
2233
                psTagSet.tagCount = ByteUtils.byteToUnsignedInt(psDGN.abyElem[44]) +
2234
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[45]) * 256);
2235
                psTagSet.flags = ByteUtils.byteToUnsignedInt(psDGN.abyElem[46]) +
2236
                        (ByteUtils.byteToUnsignedInt(psDGN.abyElem[47]) * 256);
2237

    
2238
                int[] fin = new int[1];
2239
                fin[0] = 0;
2240

    
2241
                byte[] temp = new byte[elemento.attr_bytes];
2242
                System.arraycopy(psDGN.abyElem, 48, temp, 0, psDGN.abyElem.length - 48);
2243

    
2244
                psTagSet.tagSetName = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2245
                                                                                                 .toCharArray());
2246

    
2247
                /* -------------------------------------------------------------------- */
2248
                /*      Get the tag set number out of the attributes, if available.     */
2249
                /* -------------------------------------------------------------------- */
2250
                psTagSet.tagSet = -1;
2251

    
2252
                if ((psTagSet.attr_bytes >= 8) &&
2253
                                (psTagSet.attr_data[0] == (byte) 0x03) &&
2254
                                (psTagSet.attr_data[1] == (byte) 0x10) &&
2255
                                (psTagSet.attr_data[2] == (byte) 0x2f) &&
2256
                                (psTagSet.attr_data[3] == (byte) 0x7d)) {
2257
                        psTagSet.tagSet = psTagSet.attr_data[4] +
2258
                                (psTagSet.attr_data[5] * 256);
2259
                }
2260

    
2261
                /* -------------------------------------------------------------------- */
2262
                /*      Parse each of the tag definitions.                              */
2263
                /* -------------------------------------------------------------------- */
2264
                //psTagSet.tagList = (DGNTagDef *)        CPLMalloc(sizeof(DGNTagDef) * psTagSet->tagCount);
2265
                nDataOffset = 48 + psTagSet.tagSetName.length + 1 + 1;
2266

    
2267
                for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2268
                        DGNTagDef tagDef = new DGNTagDef();
2269

    
2270
                        //= psTagSet.tagList + iTag;
2271
                        tagDef.id = iTag;
2272

    
2273
                        //CPLAssert( nDataOffset < psDGN.nElemBytes );
2274
                        /* collect tag name. */
2275
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2276
                                psDGN.abyElem.length);
2277
                        fin[0] = 0;
2278
                        tagDef.name = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2279
                                                                                         .toCharArray());
2280
                        nDataOffset += ((tagDef.name.length) + 1);
2281

    
2282
                        /* Get tag id */
2283
                        tagDef.id = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset]) +
2284
                                (ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2285
                        nDataOffset += 2;
2286

    
2287
                        /* Get User Prompt */
2288
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2289
                                psDGN.abyElem.length);
2290
                        fin[0] = 0;
2291
                        tagDef.prompt = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2292
                                                                                           .toCharArray());
2293
                        nDataOffset += ((tagDef.prompt.length) + 1);
2294

    
2295
                        /* Get type */
2296
                        tagDef.type = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset]) +
2297
                                (ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2298
                        nDataOffset += 2;
2299

    
2300
                        /* skip five zeros */
2301
                        nDataOffset += 5;
2302

    
2303
                        /* Get the default */
2304
                        if (tagDef.type == 1) {
2305
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2306
                                        psDGN.abyElem.length);
2307
                                fin[0] = 0;
2308
                                tagDef.defaultValue.string = CPLStrdup(ByteUtils.bytesToString(
2309
                                                        temp, fin).toCharArray());
2310
                                nDataOffset += (tagDef.defaultValue.string.length + 1);
2311
                        } else if ((tagDef.type == 3) || (tagDef.type == 5)) {
2312
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 4);
2313
                                fin[0] = 0;
2314
                                tagDef.defaultValue.integer = ByteUtils.bytesToLong(temp, fin);
2315

    
2316
                                //memcpy( (tagDef.defaultValue.integer),psDGN.abyElem + nDataOffset, 4 );
2317
                                tagDef.defaultValue.integer = CPL_LSBWORD32((int) tagDef.defaultValue.integer);
2318
                                nDataOffset += 4;
2319
                        } else if (tagDef.type == 4) {
2320
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 8);
2321
                                fin[0] = 0;
2322
                                tagDef.defaultValue.real = ByteUtils.bytesToDouble(temp, fin);
2323

    
2324
                                //memcpy( (tagDef.defaultValue.real),        psDGN.abyElem + nDataOffset, 8 );
2325
                                DGNParseIEEE(tagDef.defaultValue.real);
2326
                                nDataOffset += 8;
2327
                        } else {
2328
                                nDataOffset += 4;
2329
                        }
2330
                }
2331

    
2332
                return psTagSet;
2333
        }
2334

    
2335
        /**
2336
         * DOCUMENT ME!
2337
         *
2338
         * @param psDGN DOCUMENT ME!
2339
         * @param nOptions DOCUMENT ME!
2340
         */
2341
        private void DGNSetOptions(DGNInfo psDGN, int nOptions) {
2342
                psDGN.options = nOptions;
2343
        }
2344

    
2345
        /**
2346
         * DOCUMENT ME!
2347
         *
2348
         * @param psDGN DOCUMENT ME!
2349
         * @param dfXMin DOCUMENT ME!
2350
         * @param dfYMin DOCUMENT ME!
2351
         * @param dfXMax DOCUMENT ME!
2352
         * @param dfYMax DOCUMENT ME!
2353
         */
2354
        private void DGNSetSpatialFilter(DGNInfo psDGN, double dfXMin,
2355
                double dfYMin, double dfXMax, double dfYMax) {
2356
                if ((dfXMin == 0.0) && (dfXMax == 0.0) && (dfYMin == 0.0) &&
2357
                                (dfYMax == 0.0)) {
2358
                        psDGN.has_spatial_filter = FALSE;
2359

    
2360
                        return;
2361
                }
2362

    
2363
                psDGN.has_spatial_filter = TRUE;
2364
                psDGN.sf_converted_to_uor = FALSE;
2365

    
2366
                psDGN.sf_min_x_geo = dfXMin;
2367
                psDGN.sf_min_y_geo = dfYMin;
2368
                psDGN.sf_max_x_geo = dfXMax;
2369
                psDGN.sf_max_y_geo = dfYMax;
2370

    
2371
                DGNSpatialFilterToUOR(psDGN);
2372
        }
2373

    
2374
        /**
2375
         * Muestra por consola los elementos que contiene el DGN.
2376
         *
2377
         * @param psInfo Informaci?n del DGN.
2378
         * @param psElement elemento
2379
         * @param fp path del fichero.
2380
         */
2381
        public void DGNDumpElement(DGNInfo psInfo, DGNElemCore psElement, String fp) {
2382
                //DGNInfo *psInfo = (DGNInfo *) hDGN;
2383
                //System.out.println("\n");
2384
                System.out.println("Element:" + DGNTypeToName(psElement.type) +
2385
                        " Level:" + psElement.level + " id:" + psElement.element_id);
2386

    
2387
                if (psElement.complex != 0) {
2388
                        System.out.println("(Complex) ");
2389
                }
2390

    
2391
                if (psElement.deleted != 0) {
2392
                        System.out.println("(DELETED) ");
2393
                }
2394

    
2395
                System.out.println("  offset=" + psElement.offset + " size=" +
2396
                        psElement.size + " bytes\n");
2397

    
2398
                System.out.println("  graphic_group:" + psElement.graphic_group +
2399
                        " color:" + psElement.color + " weight:" + psElement.weight +
2400
                        "style:" + psElement.style + "\n");
2401

    
2402
                if (psElement.properties != 0) {
2403
                        int nClass;
2404

    
2405
                        System.out.println("  properties=" + psElement.properties);
2406

    
2407
                        if ((psElement.properties & DGNFileHeader.DGNPF_HOLE) != 0) {
2408
                                System.out.println(",HOLE");
2409
                        }
2410

    
2411
                        if ((psElement.properties & DGNFileHeader.DGNPF_SNAPPABLE) != 0) {
2412
                                System.out.println(",SNAPPABLE");
2413
                        }
2414

    
2415
                        if ((psElement.properties & DGNFileHeader.DGNPF_PLANAR) != 0) {
2416
                                System.out.println(",PLANAR");
2417
                        }
2418

    
2419
                        if ((psElement.properties & DGNFileHeader.DGNPF_ORIENTATION) != 0) {
2420
                                System.out.println(",ORIENTATION");
2421
                        }
2422

    
2423
                        if ((psElement.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
2424
                                System.out.println(",ATTRIBUTES");
2425
                        }
2426

    
2427
                        if ((psElement.properties & DGNFileHeader.DGNPF_MODIFIED) != 0) {
2428
                                System.out.println(",MODIFIED");
2429
                        }
2430

    
2431
                        if ((psElement.properties & DGNFileHeader.DGNPF_NEW) != 0) {
2432
                                System.out.println(",NEW");
2433
                        }
2434

    
2435
                        if ((psElement.properties & DGNFileHeader.DGNPF_LOCKED) != 0) {
2436
                                System.out.println(",LOCKED");
2437
                        }
2438

    
2439
                        nClass = psElement.properties & DGNFileHeader.DGNPF_CLASS;
2440

    
2441
                        if (nClass == DGNFileHeader.DGNC_PATTERN_COMPONENT) {
2442
                                System.out.println(",PATTERN_COMPONENT");
2443
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_ELEMENT) {
2444
                                System.out.println(",CONSTRUCTION ELEMENT");
2445
                        } else if (nClass == DGNFileHeader.DGNC_DIMENSION_ELEMENT) {
2446
                                System.out.println(",DIMENSION ELEMENT");
2447
                        } else if (nClass == DGNFileHeader.DGNC_PRIMARY_RULE_ELEMENT) {
2448
                                System.out.println(",PRIMARY RULE ELEMENT");
2449
                        } else if (nClass == DGNFileHeader.DGNC_LINEAR_PATTERNED_ELEMENT) {
2450
                                System.out.println(",LINEAR PATTERNED ELEMENT");
2451
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_RULE_ELEMENT) {
2452
                                System.out.println(",CONSTRUCTION_RULE_ELEMENT");
2453
                        }
2454

    
2455
                        // System.out.println("\n");
2456
                }
2457

    
2458
                switch (psElement.stype) {
2459
                        case DGNFileHeader.DGNST_MULTIPOINT: {
2460
                                DGNElemMultiPoint psLine = new DGNElemMultiPoint();
2461
                                psLine = (DGNElemMultiPoint) psElement;
2462

    
2463
                                int i;
2464

    
2465
                                for (i = 0; i < psLine.num_vertices; i++)
2466
                                        System.out.println(psLine.vertices[i].x + "," +
2467
                                                psLine.vertices[i].y + "," + psLine.vertices[i].z);
2468
                        }
2469

    
2470
                        break;
2471

    
2472
                        case DGNFileHeader.DGNST_CELL_HEADER: {
2473
                                DGNElemCellHeader psCell = new DGNElemCellHeader();
2474
                                psCell = (DGNElemCellHeader) psElement;
2475

    
2476
                                System.out.println("  totlength=" + psCell.totlength +
2477
                                        ", name=" + psCell.name.toString() + " class=" +
2478
                                        psCell.cclass + " levels=" + psCell.levels[0] +
2479
                                        psCell.levels[1] + psCell.levels[2] + psCell.levels[3] +
2480
                                        "\n");
2481
                                System.out.println("  rnglow=(" + psCell.rnglow.x + "," +
2482
                                        psCell.rnglow.y + "), rnghigh=(" + psCell.rnghigh.x + "," +
2483
                                        psCell.rnghigh.y + ")\n");
2484
                                System.out.println("  origin=(" + psCell.origin.x + "," +
2485
                                        psCell.origin.y + ")\n");
2486
                                System.out.println("  xscale=" + psCell.xscale + ",yscale=" +
2487
                                        psCell.yscale + ", rotation=" + psCell.rotation + "\n");
2488
                        }
2489

    
2490
                        break;
2491

    
2492
                        case DGNFileHeader.DGNST_CELL_LIBRARY: {
2493
                                DGNElemCellLibrary psCell = new DGNElemCellLibrary();
2494
                                psCell = (DGNElemCellLibrary) psElement;
2495

    
2496
                                System.out.println("  name=" + psCell.name.toString() +
2497
                                        " class=" + psCell.cclass + " levels=" + psCell.levels[0] +
2498
                                        psCell.levels[1] + psCell.levels[2] + psCell.levels[3] +
2499
                                        " numwords=" + psCell.numwords + "\n");
2500
                                System.out.println("  dispsymb=" + psCell.dispsymb +
2501
                                        ", description=" + psCell.description + "\n");
2502
                        }
2503

    
2504
                        break;
2505

    
2506
                        case DGNFileHeader.DGNST_ARC: {
2507
                                DGNElemArc psArc = new DGNElemArc();
2508
                                psArc = (DGNElemArc) psElement;
2509

    
2510
                                if (psInfo.dimension == 2) {
2511
                                        System.out.println("  origin=(" + psArc.origin.x + "," +
2512
                                                psArc.origin.y + "), rotation=" + psArc.rotation +
2513
                                                "\n");
2514
                                } else {
2515
                                        System.out.println("  origin=(" + psArc.origin.x + "," +
2516
                                                psArc.origin.y + "," + psArc.origin.z + "), quat=" +
2517
                                                psArc.quat[0] + "," + psArc.quat[1] + "," +
2518
                                                psArc.quat[2] + "," + psArc.quat[3] + "\n");
2519
                                }
2520

    
2521
                                System.out.println("  axes=(" + psArc.primary_axis + "," +
2522
                                        psArc.secondary_axis + "), start angle=" + psArc.startang +
2523
                                        ", sweep=" + psArc.sweepang + "\n");
2524
                        }
2525

    
2526
                        break;
2527

    
2528
                        case DGNFileHeader.DGNST_TEXT: {
2529
                                DGNElemText psText = new DGNElemText();
2530
                                psText = (DGNElemText) psElement;
2531

    
2532
                                System.out.println("  origin=(" + psText.origin.x +
2533
                                        psText.origin.y + ") rotation=" + psText.rotation + "\n" +
2534
                                        "  font=" + psText.font_id + " just=" +
2535
                                        psText.justification + "length_mult=" + psText.length_mult +
2536
                                        " height_mult=" + psText.height_mult + "\n" + "  string =" +
2537
                                        new String(psText.string).toString() + "\n");
2538
                        }
2539

    
2540
                        break;
2541

    
2542
                        case DGNFileHeader.DGNST_COMPLEX_HEADER: {
2543
                                DGNElemComplexHeader psHdr = new DGNElemComplexHeader();
2544
                                psHdr = (DGNElemComplexHeader) psElement;
2545

    
2546
                                System.out.println("  totlength=" + psHdr.totlength +
2547
                                        "numelems=" + psHdr.numelems + "\n");
2548
                        }
2549

    
2550
                        break;
2551

    
2552
                        case DGNFileHeader.DGNST_COLORTABLE: {
2553
                                DGNElemColorTable psCT = new DGNElemColorTable();
2554
                                psCT = (DGNElemColorTable) psElement;
2555

    
2556
                                int i;
2557

    
2558
                                System.out.println("  screen_flag:" + psCT.screen_flag + "\n");
2559

    
2560
                                for (i = 0; i < 256; i++) {
2561
                                        System.out.println(i + ": (" + psCT.color_info[i][0] + "," +
2562
                                                psCT.color_info[i][1] + "," + psCT.color_info[i][2] +
2563
                                                ")\n");
2564
                                }
2565
                        }
2566

    
2567
                        break;
2568

    
2569
                        case DGNFileHeader.DGNST_TCB: {
2570
                                DGNElemTCB psTCB = new DGNElemTCB();
2571
                                psTCB = (DGNElemTCB) psElement;
2572

    
2573
                                int iView;
2574

    
2575
                                //psTCB.dimension=psInfo.dimension;
2576
                                System.out.println("  dimension =" + psTCB.dimension + "\n");
2577
                                System.out.println("  uor_per_subunit =" +
2578
                                        psTCB.uor_per_subunit); //+
2579

    
2580
                                // " subunits = `" + psTCB.sub_units[0] + psTCB.sub_units[1] +
2581
                                // psTCB.sub_units[2] + "'\n");
2582
                                System.out.println("  subunits_per_master =" +
2583
                                        psTCB.subunits_per_master); //+ " master_units = `" +
2584

    
2585
                                // psTCB.master_units[0] + psTCB.master_units[1] +
2586
                                // psTCB.master_units[2] + "'\n");
2587
                                System.out.println("  origin = (" + psTCB.origin_x + "," +
2588
                                        psTCB.origin_y + "," + psTCB.origin_z + ")\n");
2589

    
2590
                                for (iView = 0; iView < 8; iView++) {
2591
                                        DGNViewInfo psView = psTCB.views[iView];
2592

    
2593
                                        //DGNParseTCB(psInfo);
2594
                                        System.out.println("View  " + iView + ": flags= " +
2595
                                                Integer.toHexString(psView.flags) + " levels= " +
2596
                                                psView.levels[0] + "" + psView.levels[1] + "" +
2597
                                                psView.levels[2] + "" + psView.levels[3] + "" +
2598
                                                psView.levels[4] + "" + psView.levels[5] + "" +
2599
                                                psView.levels[6] + "" + psView.levels[7] + "\n");
2600
                                        System.out.println("origin=( " + psView.origin.x + "," +
2601
                                                psView.origin.y + "," + psView.origin.z +
2602
                                                ")\n        delta=(" + psView.delta.x + "," +
2603
                                                psView.delta.y + "," + psView.delta.z + ")\n");
2604

    
2605
                                        System.out.println("trans=( " + psView.transmatrx[0] + "," +
2606
                                                psView.transmatrx[1] + "," + psView.transmatrx[2] +
2607
                                                "," + psView.transmatrx[3] + "," +
2608
                                                psView.transmatrx[4] + "," + psView.transmatrx[5] +
2609
                                                "," + psView.transmatrx[6] + "," +
2610
                                                psView.transmatrx[7] + "," + psView.transmatrx[8] +
2611
                                                ")\n");
2612
                                }
2613
                        }
2614

    
2615
                        break;
2616

    
2617
                        case DGNFileHeader.DGNST_TAG_SET: {
2618
                                DGNElemTagSet psTagSet = new DGNElemTagSet();
2619
                                psTagSet = (DGNElemTagSet) psElement;
2620

    
2621
                                int iTag;
2622

    
2623
                                System.out.println("  tagSetName=" +
2624
                                        psTagSet.tagSetName.toString() + " tagSet=" +
2625
                                        psTagSet.tagSet + " tagCount=" + psTagSet.tagCount +
2626
                                        " flags=" + psTagSet.flags + "\n");
2627

    
2628
                                for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2629
                                        DGNTagDef psTagDef = psTagSet.tagList[iTag];
2630

    
2631
                                        System.out.println(psTagDef.id + ": name=" +
2632
                                                psTagDef.name.toString() + ", type=" + psTagDef.type +
2633
                                                ", prompt=" + psTagDef.prompt.toString());
2634

    
2635
                                        if (psTagDef.type == 1) {
2636
                                                System.out.println(", default=" +
2637
                                                        psTagDef.defaultValue.string.toString() + "\n");
2638
                                        } else if ((psTagDef.type == 3) || (psTagDef.type == 5)) {
2639
                                                System.out.println(", default=" +
2640
                                                        psTagDef.defaultValue.integer + "\n");
2641
                                        } else if (psTagDef.type == 4) {
2642
                                                System.out.println(", default=" +
2643
                                                        psTagDef.defaultValue.real + "\n");
2644
                                        } else {
2645
                                                System.out.println(", default=<unknown>\n");
2646
                                        }
2647
                                }
2648
                        }
2649

    
2650
                        break;
2651

    
2652
                        case DGNFileHeader.DGNST_TAG_VALUE: {
2653
                                DGNElemTagValue psTag = new DGNElemTagValue();
2654
                                psTag = (DGNElemTagValue) psElement;
2655

    
2656
                                System.out.println("  tagType=" + psTag.tagType + ", tagSet=" +
2657
                                        psTag.tagSet + ", tagIndex=" + psTag.tagIndex +
2658
                                        ", tagLength=" + psTag.tagLength + "\n");
2659

    
2660
                                if (psTag.tagType == 1) {
2661
                                        System.out.println("  value=" +
2662
                                                psTag.tagValue.string.toString() + "\n");
2663
                                } else if (psTag.tagType == 3) {
2664
                                        System.out.println("  value=" + psTag.tagValue.integer +
2665
                                                "\n");
2666
                                } else if (psTag.tagType == 4) {
2667
                                        System.out.println("  value=" + psTag.tagValue.real + "\n");
2668
                                }
2669
                        }
2670

    
2671
                        break;
2672

    
2673
                        case DGNFileHeader.DGNST_GROUP_DATA: {
2674
                                // TODO
2675
                        }
2676

    
2677
                        break;
2678

    
2679
                        default:
2680
                                break;
2681
                }
2682

    
2683
                if (psElement.attr_bytes > 0) {
2684
                        int iLink;
2685

    
2686
                        System.out.println("Attributes:" + psElement.attr_bytes + "\n");
2687

    
2688
                        for (iLink = 0; true; iLink++) {
2689
                                int[] nLinkType = new int[1];
2690
                                int[] nEntityNum = new int[1];
2691
                                int[] nMSLink = new int[1];
2692
                                int[] nLinkSize = new int[1];
2693
                                int i;
2694
                                nEntityNum[0] = 0;
2695
                                nMSLink[0] = 0;
2696

    
2697
                                byte[] pabyData;
2698

    
2699
                                pabyData = DGNGetLinkage(psInfo, psElement, iLink, nLinkType,
2700
                                                nEntityNum, nMSLink, nLinkSize);
2701

    
2702
                                if (pabyData == null) {
2703
                                        break;
2704
                                }
2705

    
2706
                                System.out.println("Type=0x" + nLinkType);
2707

    
2708
                                if ((nMSLink[0] != 0) || (nEntityNum[0] != 0)) {
2709
                                        System.out.println(", EntityNum=" + nEntityNum[0] +
2710
                                                ", MSLink=" + nMSLink[0]);
2711
                                }
2712

    
2713
                                System.out.println("\n  0x");
2714

    
2715
                                for (i = 0; i < nLinkSize[0]; i++)
2716
                                        System.out.println(pabyData[i]);
2717

    
2718
                                System.out.println("\n");
2719
                        }
2720
                }
2721
        }
2722

    
2723
        /**
2724
         * Returns requested linkage raw data.  A pointer to the raw data for the
2725
         * requested attribute linkage is returned as well as (potentially)
2726
         * various information about the linkage including the linkage type,
2727
         * database entity number and MSLink value, and the length of the raw
2728
         * linkage data in bytes. If the requested linkage (iIndex) does not exist
2729
         * a value of zero is  returned. The entity number is (loosely speaking)
2730
         * the index of the table within the current database to which the MSLINK
2731
         * value will refer.  The entity number should be used to lookup the table
2732
         * name in the MSCATALOG table.  The MSLINK value is the key value for the
2733
         * record in the target table.
2734
         *
2735
         * @param psDGN the file from which the element originated.
2736
         * @param psElement the element to report on.
2737
         * @param iIndex the zero based index of the linkage to fetch.
2738
         * @param pnLinkageType variable to return linkage type.  This may be one
2739
         *                   of the predefined DGNLT_ values or a different value. This
2740
         *                   pointer may be NULL.
2741
         * @param pnEntityNum variable to return the entity number in or NULL if
2742
         *                   not required.
2743
         * @param pnMSLink variable to return the MSLINK value in, or NULL if not
2744
         *                   required.
2745
         * @param pnLength variable to returned the linkage size in bytes or NULL.
2746
         *
2747
         * @return pointer to raw internal linkage data.  This data should not be
2748
         *                    altered or freed.  NULL returned on failure.
2749
         */
2750
        private byte[] DGNGetLinkage(DGNInfo psDGN, DGNElemCore psElement,
2751
                int iIndex, int[] pnLinkageType, int[] pnEntityNum, int[] pnMSLink,
2752
                int[] pnLength) {
2753
                int nAttrOffset;
2754
                int iLinkage;
2755
                int nLinkSize;
2756

    
2757
                for (iLinkage = 0, nAttrOffset = 0;
2758
                                (nLinkSize = DGNGetAttrLinkSize(psDGN, psElement, nAttrOffset)) != 0;
2759
                                iLinkage++, nAttrOffset += nLinkSize) {
2760
                        if (iLinkage == iIndex) {
2761
                                int nLinkageType = 0;
2762
                                int nEntityNum = 0;
2763
                                int nMSLink = 0;
2764

    
2765
                                //CPLAssert( nLinkSize > 4 );
2766
                                if ((psElement.attr_data[nAttrOffset + 0] == (byte) 0x00) &&
2767
                                                ((psElement.attr_data[nAttrOffset + 1] == (byte) 0x00) ||
2768
                                                (psElement.attr_data[nAttrOffset + 1] == (byte) 0x80))) {
2769
                                        nLinkageType = DGNFileHeader.DGNLT_DMRS;
2770
                                        nEntityNum = psElement.attr_data[nAttrOffset + 2] +
2771
                                                (psElement.attr_data[nAttrOffset + 3] * 256);
2772
                                        nMSLink = psElement.attr_data[nAttrOffset + 4] +
2773
                                                (psElement.attr_data[nAttrOffset + 5] * 256) +
2774
                                                (psElement.attr_data[nAttrOffset + 6] * 65536);
2775
                                } else {
2776
                                        nLinkageType = psElement.attr_data[nAttrOffset + 2] +
2777
                                                (psElement.attr_data[nAttrOffset + 3] * 256);
2778
                                }
2779

    
2780
                                // Possibly an external database linkage?
2781
                                if ((nLinkSize == 16) &&
2782
                                                (nLinkageType != DGNFileHeader.DGNLT_SHAPE_FILL)) {
2783
                                        nEntityNum = psElement.attr_data[nAttrOffset + 6] +
2784
                                                (psElement.attr_data[nAttrOffset + 7] * 256);
2785
                                        nMSLink = psElement.attr_data[nAttrOffset + 8] +
2786
                                                (psElement.attr_data[nAttrOffset + 9] * 256) +
2787
                                                (psElement.attr_data[nAttrOffset + 10] * 65536) +
2788
                                                (psElement.attr_data[nAttrOffset + 11] * 65536 * 256);
2789
                                }
2790

    
2791
                                if (pnLinkageType != null) {
2792
                                        pnLinkageType[0] = nLinkageType;
2793
                                }
2794

    
2795
                                if (pnEntityNum != null) {
2796
                                        pnEntityNum[0] = nEntityNum;
2797
                                }
2798

    
2799
                                if (pnMSLink != null) {
2800
                                        pnMSLink[0] = nMSLink;
2801
                                }
2802

    
2803
                                if (pnLength != null) {
2804
                                        pnLength[0] = nLinkSize;
2805
                                }
2806

    
2807
                                byte[] temp = new byte[psElement.attr_data.length -
2808
                                        nAttrOffset];
2809
                                System.arraycopy(psElement.attr_data, nAttrOffset, temp, 0,
2810
                                        psElement.attr_data.length - nAttrOffset);
2811

    
2812
                                return temp;
2813
                        }
2814
                }
2815

    
2816
                return null;
2817
        }
2818

    
2819
        /**
2820
         * Devuelve el tama?o de los atributos de un elemento.
2821
         *
2822
         * @param psDGN Informaci?n del DGN.
2823
         * @param psElement elemento.
2824
         * @param nOffset indice donde se encuentra el elemento.
2825
         *
2826
         * @return Entero que representa el Tama?o.
2827
         */
2828
        private int DGNGetAttrLinkSize(DGNInfo psDGN, DGNElemCore psElement,
2829
                int nOffset) {
2830
                if (psElement.attr_bytes < (nOffset + 4)) {
2831
                        return 0;
2832
                }
2833

    
2834
                /* DMRS Linkage */
2835
                if (((psElement.attr_data[nOffset + 0] == 0) &&
2836
                                (psElement.attr_data[nOffset + 1] == 0)) ||
2837
                                ((psElement.attr_data[nOffset + 0] == 0) &&
2838
                                (psElement.attr_data[nOffset + 1] == (byte) 0x80))) {
2839
                        return 8;
2840
                }
2841

    
2842
                /* If low order bit of second byte is set, first byte is length */
2843
                if ((psElement.attr_data[nOffset + 1] & (byte) 0x10) != FALSE) {
2844
                        return (psElement.attr_data[nOffset + 0] * 2) + 2;
2845
                }
2846

    
2847
                /* unknown */
2848
                return 0;
2849
        }
2850

    
2851
        /**
2852
         * A partir de un entero devuelve el un String con el tipo del elemento.
2853
         *
2854
         * @param nType tipo.
2855
         *
2856
         * @return String con el nombre del elemento.
2857
         */
2858
        private String DGNTypeToName(int nType) {
2859
                //char[]        szNumericResult=new char[16];
2860
                switch (nType) {
2861
                        case DGNFileHeader.DGNT_CELL_LIBRARY:
2862
                                return "Cell Library";
2863

    
2864
                        case DGNFileHeader.DGNT_CELL_HEADER:
2865
                                return "Cell Header";
2866

    
2867
                        case DGNFileHeader.DGNT_LINE:
2868
                                return "Line";
2869

    
2870
                        case DGNFileHeader.DGNT_LINE_STRING:
2871
                                return "Line String";
2872

    
2873
                        case DGNFileHeader.DGNT_GROUP_DATA:
2874
                                return "Group Data";
2875

    
2876
                        case DGNFileHeader.DGNT_SHAPE:
2877
                                return "Shape";
2878

    
2879
                        case DGNFileHeader.DGNT_TEXT_NODE:
2880
                                return "Text Node";
2881

    
2882
                        case DGNFileHeader.DGNT_DIGITIZER_SETUP:
2883
                                return "Digitizer Setup";
2884

    
2885
                        case DGNFileHeader.DGNT_TCB:
2886
                                return "TCB";
2887

    
2888
                        case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
2889
                                return "Level Symbology";
2890

    
2891
                        case DGNFileHeader.DGNT_CURVE:
2892
                                return "Curve";
2893

    
2894
                        case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
2895
                                return "Complex Chain Header";
2896

    
2897
                        case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
2898
                                return "Complex Shape Header";
2899

    
2900
                        case DGNFileHeader.DGNT_ELLIPSE:
2901
                                return "Ellipse";
2902

    
2903
                        case DGNFileHeader.DGNT_ARC:
2904
                                return "Arc";
2905

    
2906
                        case DGNFileHeader.DGNT_TEXT:
2907
                                return "Text";
2908

    
2909
                        case DGNFileHeader.DGNT_BSPLINE:
2910
                                return "B-Spline";
2911

    
2912
                        case DGNFileHeader.DGNT_APPLICATION_ELEM:
2913
                                return "Application Element";
2914

    
2915
                        case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
2916
                                return "Shared Cell Definition";
2917

    
2918
                        case DGNFileHeader.DGNT_SHARED_CELL_ELEM:
2919
                                return "Shared Cell Element";
2920

    
2921
                        case DGNFileHeader.DGNT_TAG_VALUE:
2922
                                return "Tag Value";
2923

    
2924
                        default:
2925
                                System.out.println(nType);
2926

    
2927
                                return "Fallo";
2928
                }
2929
        }
2930

    
2931
        /**
2932
         * Muestra por consola la fila de un elemento.
2933
         *
2934
         * @param psDGN informaci?n del DGN.
2935
         * @param psCore elemento
2936
         * @param fpOut path del fichero DGN.
2937
         */
2938
        private void DGNDumpRawElement(DGNInfo psDGN, DGNElemCore psCore,
2939
                String fpOut) {
2940
                int i;
2941
                int iChar = 0;
2942
                byte[] szLine = new byte[80];
2943

    
2944
                //System.out.println("  Raw Data (" + psCore.raw_bytes + " bytes):\n");
2945
                for (i = 0; i < psCore.raw_bytes; i++) {
2946
                        byte[] szHex = new byte[3];
2947

    
2948
                        if ((i % 16) == 0) {
2949
                                int[] f = new int[1];
2950
                                byte[] temp = new byte[4];
2951
                                f[0] = 0;
2952
                                ByteUtils.intToBytes(i, temp, f);
2953
                                System.arraycopy(temp, 0, szLine, 0, 4);
2954

    
2955
                                ////System.out.println( szLine.toString()+","+ i );
2956
                                iChar = 0;
2957
                        }
2958

    
2959
                        szHex[0] = psCore.raw_data[i];
2960
                        szHex[1] = (byte) 0x00;
2961

    
2962
                        //System.arraycopy(psCore.raw_data,0,szHex,0,3);
2963
                        ////System.out.println( szHex.toString()+","+psCore.raw_data.toString() );
2964
                        //strncpy( szLine+8+iChar*2, szHex, 2 );/**no se */
2965
                        System.arraycopy(szHex, 0, szLine, 8 + (iChar * 2), 2);
2966

    
2967
                        if ((psCore.raw_data[i] < 32) || (psCore.raw_data[i] > 127)) {
2968
                                szLine[42 + iChar] = '.';
2969
                        } else {
2970
                                szLine[42 + iChar] = psCore.raw_data[i];
2971
                        }
2972

    
2973
                        if ((i == (psCore.raw_bytes - 1)) || (((i + 1) % 16) == 0)) {
2974
                                ////System.out.println(szLine.toString()+"\n" );
2975
                                int[] f = new int[1];
2976
                                f[0] = 0;
2977

    
2978
                                //ByteUtils.bytesToInt(szLine,f);
2979
                                //System.out.println(ByteUtils.bytesToInt(szLine, f) + " : ");
2980
                                //ByteUtils.print_bytes(szLine,8,74);
2981
                                byte[] temp = new byte[1];
2982
                                byte[] temp1 = new byte[16];
2983
                                int k = 0;
2984

    
2985
                                for (int j = 1; j < 32; j = j + 2) {
2986
                                        System.arraycopy(szLine, j + 7, temp, 0, 1);
2987
                                        temp1[k] = temp[0];
2988
                                        k++;
2989
                                }
2990

    
2991
                                //System.out.println(ByteUtils.print_bytes(temp1));
2992
                                ////System.out.println(ByteUtils.print_bytes(szLine,7,41));
2993
                                f[0] = 42;
2994

    
2995
                                char[] tempchar = new char[16];
2996

    
2997
                                for (int j = 0; j < 16; j++) {
2998
                                        tempchar[j] = (char) szLine[42 + j];
2999
                                }
3000

    
3001
                                //System.out.println(String.copyValueOf(tempchar));
3002
                        }
3003

    
3004
                        iChar++;
3005
                }
3006
        }
3007

    
3008
        /**
3009
         * Devuelve el extent del elemento.
3010
         *
3011
         * @param psDGN Informaci?n del DGN.
3012
         * @param padfExtents doubles que representan el rect?ngulo del extent.
3013
         *
3014
         * @return Entero que muestra si se ha calculado correctamente.
3015
         */
3016
        private int DGNGetExtents(DGNInfo psDGN, double[] padfExtents) {
3017
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3018
                DGNPoint sMin = new DGNPoint();
3019
                DGNPoint sMax = new DGNPoint();
3020

    
3021
                DGNBuildIndex(psDGN);
3022

    
3023
                if (psDGN.got_bounds == FALSE) {
3024
                        return FALSE;
3025
                }
3026

    
3027
                double minX = psDGN.min_x;
3028
                double minY = psDGN.min_y;
3029
                double minZ = psDGN.min_z;
3030
                System.out.println("psDGN.min" + " x= " + psDGN.min_x + " y= " +
3031
                        psDGN.min_y);
3032

    
3033
                if (minX < 0) {
3034
                        minX = minX + (2 * ((long) Integer.MAX_VALUE + 1));
3035
                        System.out.println("minX" + minX);
3036
                }
3037

    
3038
                if (minY < 0) {
3039
                        minY = minY + (2 * ((long) Integer.MAX_VALUE + 1));
3040
                        System.out.println("minY" + minY);
3041
                }
3042

    
3043
                if (minZ < 0) {
3044
                        minZ = minZ + (2 * ((long) Integer.MAX_VALUE + 1));
3045
                }
3046

    
3047
                sMin.x = minX - 2147483648.0;
3048
                sMin.y = minY - 2147483648.0;
3049
                sMin.z = minZ - 2147483648.0;
3050

    
3051
                DGNTransformPoint(psDGN, sMin);
3052

    
3053
                padfExtents[0] = sMin.x;
3054
                padfExtents[1] = sMin.y;
3055
                padfExtents[2] = sMin.z;
3056

    
3057
                double maxX = psDGN.max_x;
3058
                double maxY = psDGN.max_y;
3059
                double maxZ = psDGN.max_z;
3060

    
3061
                //System.out.println("psDGN.max"+ " x= "+psDGN.max_x+" y= "+psDGN.max_y);
3062
                if (maxX < 0) {
3063
                        maxX = maxX + (2 * ((long) Integer.MAX_VALUE + 1));
3064

    
3065
                        //System.out.println("maxX"+maxX);
3066
                }
3067

    
3068
                if (maxY < 0) {
3069
                        maxY = maxY + (2 * ((long) Integer.MAX_VALUE + 1));
3070

    
3071
                        //System.out.println("maxY"+maxY);
3072
                }
3073

    
3074
                if (maxZ < 0) {
3075
                        maxZ = maxZ + (2 * ((long) Integer.MAX_VALUE + 1));
3076
                }
3077

    
3078
                sMax.x = maxX - 2147483648.0;
3079
                sMax.y = maxY - 2147483648.0;
3080
                sMax.z = maxZ - 2147483648.0;
3081

    
3082
                DGNTransformPoint(psDGN, sMax);
3083

    
3084
                padfExtents[3] = sMax.x;
3085
                padfExtents[4] = sMax.y;
3086
                padfExtents[5] = sMax.z;
3087

    
3088
                return TRUE;
3089
        }
3090

    
3091
        /**
3092
         * Construye un ?ndice al DGN.
3093
         *
3094
         * @param psDGN Informaci?n del DGN.
3095
         */
3096
        private void DGNBuildIndex(DGNInfo psDGN) {
3097
                DGNElemCore elemento = new DGNElemCore();
3098
                int nMaxElements;
3099
                int nType;
3100
                int nLevel;
3101
                long nLastOffset;
3102

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

    
3107
                psDGN.index_built = TRUE;
3108

    
3109
                //DGNRewind( psDGN );
3110
                nMaxElements = 0;
3111

    
3112
                //nLastOffset = VSIFTell( psDGN.fp );
3113
                nLastOffset = bb.position(); //psDGN.ftall;
3114

    
3115
                while (DGNLoadRawElement(psDGN, elemento) != FALSE) {
3116
                        DGNElementInfo psEI; // = new DGNElementInfo();
3117

    
3118
                        if (psDGN.element_count == nMaxElements) {
3119
                                int oldMax = nMaxElements;
3120
                                nMaxElements = (int) (nMaxElements * 1.5) + 500;
3121

    
3122
                                DGNElementInfo[] nuevo = new DGNElementInfo[nMaxElements];
3123

    
3124
                                for (int i = 0; i < oldMax; i++)
3125
                                        nuevo[i] = psDGN.element_index[i];
3126

    
3127
                                psDGN.element_index = nuevo;
3128

    
3129
                                //psDGN.element_index = (DGNElementInfo *)        CPLRealloc( psDGN.element_index,
3130
                                //                                nMaxElements * sizeof(DGNElementInfo) );
3131
                        }
3132

    
3133
                        psDGN.element_index[psDGN.element_count] = new DGNElementInfo();
3134
                        psEI = psDGN.element_index[psDGN.element_count];
3135
                        psEI.level = elemento.level;
3136
                        psEI.type = elemento.type;
3137
                        psEI.flags = 0;
3138
                        psEI.offset = nLastOffset;
3139

    
3140
                        if ((psDGN.abyElem[0] * (byte) 0x80) == (byte) 0x80) {
3141
                                psEI.flags |= DGNFileHeader.DGNEIF_COMPLEX;
3142
                        }
3143

    
3144
                        if ((psDGN.abyElem[1] * (byte) 0x80) == (byte) 0x80) {
3145
                                psEI.flags |= DGNFileHeader.DGNEIF_DELETED;
3146
                        }
3147

    
3148
                        if ((elemento.type == DGNFileHeader.DGNT_LINE) ||
3149
                                        (elemento.type == DGNFileHeader.DGNT_LINE_STRING) ||
3150
                                        (elemento.type == DGNFileHeader.DGNT_SHAPE) ||
3151
                                        (elemento.type == DGNFileHeader.DGNT_CURVE) ||
3152
                                        (elemento.type == DGNFileHeader.DGNT_BSPLINE)) {
3153
                                psEI.stype = DGNFileHeader.DGNST_MULTIPOINT;
3154
                        } else if ((elemento.type == DGNFileHeader.DGNT_GROUP_DATA) &&
3155
                                        (elemento.level == DGNFileHeader.DGN_GDL_COLOR_TABLE)) {
3156
                                DGNElemCore psCT = DGNParseColorTable(psDGN);
3157

    
3158
                                //DGNFreeElement( psDGN, psCT );
3159
                                System.err.println("TABLA DE COLORES!!");
3160
                                psEI.stype = DGNFileHeader.DGNST_COLORTABLE;
3161
                                m_colorTable = (DGNElemColorTable) psCT;
3162

    
3163
                                // DGNDumpElement(psDGN,psCT,"");
3164
                        } else if ((elemento.type == DGNFileHeader.DGNT_ELLIPSE) ||
3165
                                        (elemento.type == DGNFileHeader.DGNT_ARC)) {
3166
                                psEI.stype = DGNFileHeader.DGNST_ARC;
3167
                        } else if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) ||
3168
                                        (elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)) {
3169
                                psEI.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
3170
                        } else if (elemento.type == DGNFileHeader.DGNT_TEXT) {
3171
                                psEI.stype = DGNFileHeader.DGNST_TEXT;
3172
                        } else if (elemento.type == DGNFileHeader.DGNT_TAG_VALUE) {
3173
                                psEI.stype = DGNFileHeader.DGNST_TAG_VALUE;
3174
                        } else if (elemento.type == DGNFileHeader.DGNT_APPLICATION_ELEM) {
3175
                                if (elemento.level == 24) {
3176
                                        psEI.stype = DGNFileHeader.DGNST_TAG_SET;
3177
                                } else {
3178
                                        psEI.stype = DGNFileHeader.DGNST_CORE;
3179
                                }
3180
                        } else if (elemento.type == DGNFileHeader.DGNT_TCB) {
3181
                                DGNElemCore psTCB = DGNParseTCB(psDGN);
3182

    
3183
                                //DGNFreeElement( psDGN, psTCB );
3184
                                psEI.stype = DGNFileHeader.DGNST_TCB;
3185
                        } else {
3186
                                psEI.stype = DGNFileHeader.DGNST_CORE;
3187
                        }
3188

    
3189
                        //DGNInfo tempo = new DGNInfo();
3190
                        double[] anRegion;
3191

    
3192
                        if (((psEI.flags & DGNFileHeader.DGNEIF_DELETED) == FALSE) &
3193
                                        ((psEI.flags & DGNFileHeader.DGNEIF_COMPLEX) == FALSE) &
3194
                                        ((anRegion = DGNGetRawExtents(psDGN, null, elemento)) != null)) {
3195
                                //        #ifdef notdef
3196
                                // System.out.println( "element_count"+psDGN.element_count+"anRegion[]"+("xmin"+anRegion[0])+"xmax"+anRegion[1]+"ymin"+anRegion[3]+"ymax"+anRegion[4]+ 2147483648.0 );
3197
                                //#endif
3198

    
3199
                                /*        double aux=0;
3200
                                   if (anRegion[0]>anRegion[3]){
3201
                                           aux=anRegion[3];
3202
                                           anRegion[3]=anRegion[0];
3203
                                           anRegion[0]=anRegion[3];
3204
                                   }
3205
                                   if (anRegion[1]>anRegion[4]){
3206
                                                                           aux=anRegion[4];
3207
                                                                           anRegion[4]=anRegion[1];
3208
                                                                           anRegion[1]=anRegion[4];
3209
                                                                   }*/
3210
                                if (psDGN.got_bounds != FALSE) {
3211
                                        psDGN.min_x = Math.min(psDGN.min_x, anRegion[0]);
3212
                                        psDGN.min_y = Math.min(psDGN.min_y, anRegion[1]);
3213
                                        psDGN.min_z = Math.min(psDGN.min_z, anRegion[2]);
3214
                                        psDGN.max_x = Math.max(psDGN.max_x, anRegion[3]);
3215
                                        psDGN.max_y = Math.max(psDGN.max_y, anRegion[4]);
3216
                                        psDGN.max_z = Math.max(psDGN.max_z, anRegion[5]);
3217
                                } else {
3218
                                        psDGN.min_x = anRegion[0];
3219
                                        psDGN.min_y = anRegion[1];
3220
                                        psDGN.min_z = anRegion[2];
3221
                                        psDGN.max_x = anRegion[3];
3222
                                        psDGN.max_y = anRegion[4];
3223
                                        psDGN.max_z = anRegion[5];
3224

    
3225
                                        //memcpy( (psDGN.min_x), anRegion, sizeof(long) * 6 );
3226
                                        psDGN.got_bounds = TRUE;
3227
                                }
3228

    
3229
                                // System.out.println("xmin"+anRegion[0]+"xmax"+anRegion[3]+"ymin"+anRegion[1]+"ymax"+anRegion[4]+ "      "+2147483648.0 );
3230
                        }
3231

    
3232
                        psDGN.element_count++;
3233

    
3234
                        //nLastOffset = VSIFTell( psDGN.fp );
3235
                        nLastOffset = bb.position(); // psDGN.ftall;
3236
                }
3237

    
3238
                //DGNRewind( psDGN );
3239
                psDGN.max_element_count = nMaxElements;
3240
        }
3241

    
3242
        /**
3243
         * Devuelve el rect?ngulo que representa el extent del elemento.
3244
         *
3245
         * @param psDGN informaci?n del DGN.
3246
         * @param psElement elemento.
3247
         * @param psMin punto m?nimo.
3248
         * @param psMax punto m?ximo.
3249
         *
3250
         * @return Entero para comprobar si se ha calculado correctamente.
3251
         */
3252
        private int DGNGetElementExtents(DGNInfo psDGN, DGNElemCore psElement,
3253
                DGNPoint psMin, DGNPoint psMax) {
3254
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3255
                long[] anMin = new long[3];
3256
                long[] anMax = new long[3];
3257
                DGNInfo tempo = new DGNInfo();
3258
                double[] bResult;
3259

    
3260
                /* -------------------------------------------------------------------- */
3261
                /*      Get the extents if we have raw data in the element, or          */
3262
                /*      loaded in the file buffer.                                      */
3263
                /* -------------------------------------------------------------------- */
3264
                if (psElement.raw_data != null) {
3265
                        bResult = DGNGetRawExtents(psDGN, psElement.raw_data, psElement);
3266
                } else {
3267
                        if (psElement.element_id == (psDGN.next_element_id - 1)) {
3268
                                bResult = DGNGetRawExtents(psDGN, psDGN.abyElem, psElement);
3269
                        } else {
3270
                                /*CPLError(CE_Warning, CPLE_AppDefined,
3271
                                   "DGNGetElementExtents() fails because the requested element\n"
3272
                                   " does not have raw data available." );
3273
                                 */
3274
                                return FALSE;
3275
                        }
3276
                }
3277

    
3278
                if (bResult == null) {
3279
                        return FALSE;
3280
                }
3281

    
3282
                /* -------------------------------------------------------------------- */
3283
                /*      Transform to user coordinate system and return.  The offset     */
3284
                /*      is to convert from "binary offset" form to twos complement.     */
3285
                /* -------------------------------------------------------------------- */
3286
                psMin.x = tempo.min_x - 2147483648.0;
3287
                psMin.y = tempo.min_y - 2147483648.0;
3288
                psMin.z = tempo.min_z - 2147483648.0;
3289

    
3290
                psMax.x = tempo.max_x - 2147483648.0;
3291
                psMax.y = tempo.max_y - 2147483648.0;
3292
                psMax.z = tempo.max_z - 2147483648.0;
3293

    
3294
                DGNTransformPoint(psDGN, psMin);
3295
                DGNTransformPoint(psDGN, psMax);
3296

    
3297
                return TRUE;
3298
        }
3299

    
3300
        /**
3301
         * Devuelve los ?ndices de los elementos del DGN.
3302
         *
3303
         * @param psDGN Informaci?n del DGN.
3304
         * @param pnElementCount N?mero de elementos.
3305
         *
3306
         * @return ?ndices.
3307
         */
3308
        private DGNElementInfo[] DGNGetElementIndex(DGNInfo psDGN,
3309
                int[] pnElementCount) {
3310
                //DGNInfo        *psDGN = (DGNInfo *) hDGN;
3311
                DGNBuildIndex(psDGN);
3312

    
3313
                if (pnElementCount[0] != -1) {
3314
                        pnElementCount[0] = psDGN.element_count;
3315
                }
3316

    
3317
                return psDGN.element_index;
3318
        }
3319

    
3320
        /************************************************************************/
3321
        /*                           DGNLookupColor()                           */
3322
        /************************************************************************/
3323

    
3324
        /**
3325
         * Translate color index into RGB values. If no color table has yet been
3326
         * encountered in the file a hard-coded "default" color table will be
3327
         * used.  This seems to be what Microstation uses as a color table when
3328
         * there isn't one in a DGN file but I am not absolutely convinced it is
3329
         * appropriate.
3330
         *
3331
         * @param color_index the color index to lookup.
3332
         *
3333
         * @return TRUE on success or FALSE on failure.  May fail if color_index is
3334
         *                    out of range.
3335
         */
3336
        public Color DGNLookupColor(int color_index) {
3337
                int r;
3338
                int g;
3339
                int b;
3340

    
3341
                if ((color_index < 0) || (color_index > 255)) {
3342
                        return null;
3343
                }
3344

    
3345
                if (info.got_color_table == 0) {
3346
                        r = abyDefaultPCT[color_index][0];
3347
                        g = abyDefaultPCT[color_index][1];
3348
                        b = abyDefaultPCT[color_index][2];
3349
                } else {
3350
                        r = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][0]);
3351
                        g = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][1]);
3352
                        b = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][2]);
3353
                }
3354
                if ((r == 255) && (g == 255) && (b == 255)) {
3355
                        r = g = b = 0; // El color blanco lo devolvemos como negro.
3356
                }
3357

    
3358
                return new Color(r, g, b);
3359
        }
3360

    
3361
        /************************************************************************/
3362
        /*                        DGNGetShapeFillInfo()                         */
3363
        /************************************************************************/
3364

    
3365
        /**
3366
         * Fetch fill color for a shape. This method will check for a 0x0041 user
3367
         * attribute linkaged with fill color information for the element.  If
3368
         * found the function returns TRUE, and places the fill color in pnColor,
3369
         * otherwise FALSE is returned and pnColor is not updated.
3370
         *
3371
         * @param psElem the element.
3372
         *
3373
         * @return index of color on success or -1 on failure.
3374
         */
3375
        public int DGNGetShapeFillInfo(DGNElemCore psElem) {
3376
                int iLink;
3377
                int color_index = -1;
3378

    
3379
                for (iLink = 0; true; iLink++) {
3380
                        int[] nLinkType = new int[1];
3381
                        int[] nEntityNum = new int[1];
3382
                        int[] nMSLink = new int[1];
3383
                        int[] nLinkSize = new int[1];
3384
                        int i;
3385
                        nEntityNum[0] = 0;
3386
                        nMSLink[0] = 0;
3387

    
3388
                        byte[] pabyData;
3389

    
3390
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3391
                                        nEntityNum, nMSLink, nLinkSize);
3392

    
3393
                        if (pabyData == null) {
3394
                                return -1;
3395
                        }
3396

    
3397
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_SHAPE_FILL) &&
3398
                                        (nLinkSize[0] >= 7)) {
3399
                                color_index = ByteUtils.getUnsigned(pabyData[8]);
3400

    
3401
                                break;
3402
                        }
3403
                }
3404

    
3405
                return color_index;
3406
        }
3407

    
3408
        /************************************************************************/
3409
        /*                        DGNGetAssocID()                               */
3410
        /************************************************************************/
3411

    
3412
        /**
3413
         * Fetch association id for an element. This method will check if an
3414
         * element has an association id, and if so returns it, otherwise
3415
         * returning -1.  Association ids are kept as a user attribute linkage
3416
         * where present.
3417
         *
3418
         * @param psElem the element.
3419
         *
3420
         * @return The id or -1 on failure.
3421
         */
3422
        int DGNGetAssocID(DGNElemCore psElem) {
3423
                int iLink;
3424

    
3425
                for (iLink = 0; true; iLink++) {
3426
                        int[] nLinkType = new int[1];
3427
                        int[] nEntityNum = new int[1];
3428
                        int[] nMSLink = new int[1];
3429
                        int[] nLinkSize = new int[1];
3430
                        int i;
3431
                        nEntityNum[0] = 0;
3432
                        nMSLink[0] = 0;
3433

    
3434
                        byte[] pabyData;
3435

    
3436
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3437
                                        nEntityNum, nMSLink, nLinkSize);
3438

    
3439
                        if (pabyData == null) {
3440
                                return -1;
3441
                        }
3442

    
3443
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_ASSOC_ID) &&
3444
                                        (nLinkSize[0] >= 8)) {
3445
                                return ByteUtils.getUnsigned(pabyData[4]) +
3446
                                (ByteUtils.getUnsigned(pabyData[5]) * 256) +
3447
                                (ByteUtils.getUnsigned(pabyData[6]) * 256 * 256) +
3448
                                (ByteUtils.getUnsigned(pabyData[7]) * 256 * 256 * 256);
3449
                        }
3450
                }
3451
        }
3452
}