Statistics
| Revision:

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

History | View | Annotate | Download (98 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
import java.io.FileInputStream;
52
import java.nio.ByteBuffer;
53
import java.nio.ByteOrder;
54
import java.nio.MappedByteBuffer;
55
import java.nio.channels.FileChannel;
56

    
57

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
419
                bb.rewind();
420
        }
421

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

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

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

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

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

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

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

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

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

    
495
                return TRUE;
496
        }
497

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

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

    
523
                        FileChannel fc = fin.getChannel();
524

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

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

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

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

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

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

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

    
558
                return info;
559
        }
560

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

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

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

    
589
                return TRUE;
590
        }
591

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

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

    
611
                try {
612
                        //input=new LEDataInputStream(fin);
613
                        for (int i = 0; i < 4; i++) {
614
                                info.abyElem[i] = bb.get();
615
                                if (i==1)
616
                                        if ((info.abyElem[0] == -1) && (info.abyElem[1] == -1)) 
617
                                                return FALSE;
618
                                
619

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

    
623
                        ////System.out.println(ByteUtils.byteToUnsignedInt(info.abyElem[2])+";"+ByteUtils.byteToUnsignedInt(info.abyElem[3]));
624

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

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

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

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

    
660
                        return FALSE;
661
                }
662

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

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

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

    
675
                return TRUE;
676
        }
677

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

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

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

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

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

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

    
708
                info.sf_converted_to_uor = TRUE;
709
        }
710

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

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

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

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

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

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

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

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

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

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

    
783
                return elemento;
784
        }
785

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
900
                                break;
901

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

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

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

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

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

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

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

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

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

    
1005
                        break;
1006

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

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

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

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

    
1049
                                elemento = psCell;
1050
                        }
1051

    
1052
                        break;
1053

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

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

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

    
1096
                        break;
1097

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

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

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

    
1117
                                        return null;
1118
                                }
1119

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

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

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

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

    
1142
                                elemento = psLine;
1143
                        }
1144

    
1145
                        break;
1146

    
1147
                        case DGNFileHeader.DGNT_GROUP_DATA:
1148

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1229
                        break;
1230

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

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

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

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

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

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

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

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

    
1278
                                psEllipse.secondary_axis *= info.scale;
1279

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

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

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

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

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

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

    
1320
                        break;
1321

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

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

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

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

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

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

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

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

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

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

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

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

    
1386
                                elemento = psText;
1387
                        }
1388

    
1389
                        break;
1390

    
1391
                        case DGNFileHeader.DGNT_TCB:
1392
                                if (info.got_tcb == FALSE)
1393
                                {
1394
                                        elemento = DGNParseTCB(info);
1395
                                        elemento.level = nLevel;
1396
                                        elemento.type = nType;
1397
                                }
1398
                                break;
1399

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

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

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

    
1414
                        break;
1415

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

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

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

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

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

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

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

    
1459
                                elemento = psTag;
1460
                        }
1461

    
1462
                        break;
1463

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

    
1478
                        break;
1479
                }
1480

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

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

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

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

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

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

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

    
1522
                return DGNParseIEEE(temp);
1523
        }
1524

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

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

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

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

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

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

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

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

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

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

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

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

    
1614
                f[0] = 0;
1615

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

    
1618
                return value;
1619
        }
1620

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1783
                fin[0] = 0;
1784
                dbl = ByteUtils.bytesToDouble(dest, fin);
1785
                return dbl;
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
                System.arraycopy(psDGN.abyElem, 1240, temp1, 0, 8);
2053
                ByteBuffer buffer = ByteBuffer.wrap(psDGN.abyElem);
2054
                buffer.order(ByteOrder.LITTLE_ENDIAN);
2055
                psTCB.origin_x = buffer.getDouble(1240);
2056
                psTCB.origin_y = buffer.getDouble(1248);
2057
                psTCB.origin_z = buffer.getDouble(1256);
2058

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2147
                                //nuevo m?todo
2148
                        }
2149

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

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

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

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

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

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

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

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

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

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

    
2209
                return (pszReturn);
2210
        }
2211

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

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

    
2229
                DGNParseCore(psDGN, psTagSet);
2230

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2333
                return psTagSet;
2334
        }
2335

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

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

    
2361
                        return;
2362
                }
2363

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

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

    
2372
                DGNSpatialFilterToUOR(psDGN);
2373
        }
2374

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2464
                                int i;
2465

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

    
2471
                        break;
2472

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

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

    
2491
                        break;
2492

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

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

    
2505
                        break;
2506

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

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

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

    
2527
                        break;
2528

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

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

    
2541
                        break;
2542

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

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

    
2551
                        break;
2552

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

    
2557
                                int i;
2558

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

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

    
2568
                        break;
2569

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

    
2574
                                int iView;
2575

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

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

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

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

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

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

    
2616
                        break;
2617

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

    
2622
                                int iTag;
2623

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

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

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

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

    
2651
                        break;
2652

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

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

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

    
2672
                        break;
2673

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

    
2678
                        break;
2679

    
2680
                        default:
2681
                                break;
2682
                }
2683

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

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

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

    
2698
                                byte[] pabyData;
2699

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2813
                                return temp;
2814
                        }
2815
                }
2816

    
2817
                return null;
2818
        }
2819

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2928
                                return "Fallo";
2929
                }
2930
        }
2931

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3005
                        iChar++;
3006
                }
3007
        }
3008

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

    
3022
                DGNBuildIndex(psDGN);
3023

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

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

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

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

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

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

    
3052
                DGNTransformPoint(psDGN, sMin);
3053

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

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

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

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

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

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

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

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

    
3083
                DGNTransformPoint(psDGN, sMax);
3084

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

    
3089
                return TRUE;
3090
        }
3091

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

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

    
3108
                psDGN.index_built = TRUE;
3109

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

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

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

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

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

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

    
3128
                                psDGN.element_index = nuevo;
3129

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3233
                        psDGN.element_count++;
3234

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

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

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

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

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

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

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

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

    
3298
                return TRUE;
3299
        }
3300

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

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

    
3318
                return psDGN.element_index;
3319
        }
3320

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

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

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

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

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

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

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

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

    
3389
                        byte[] pabyData;
3390

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

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

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

    
3402
                                break;
3403
                        }
3404
                }
3405

    
3406
                return color_index;
3407
        }
3408

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

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

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

    
3435
                        byte[] pabyData;
3436

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

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

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