Statistics
| Revision:

root / trunk / libraries / libDataSourceBaseDrivers / src / org / gvsig / data / datastores / vectorial / driver / dgn / filedgn / DGNReader.java @ 19618

History | View | Annotate | Download (102 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 org.gvsig.data.datastores.vectorial.driver.dgn.filedgn;
48

    
49
import java.awt.Color;
50
import java.awt.geom.Rectangle2D;
51
import java.io.FileInputStream;
52
import java.io.FileNotFoundException;
53
import java.nio.ByteBuffer;
54
import java.nio.ByteOrder;
55
import java.nio.MappedByteBuffer;
56
import java.nio.channels.FileChannel;
57

    
58
import org.gvsig.data.exception.ReadException;
59

    
60

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
422
                bb.rewind();
423
        }
424

    
425
        /* public Color getColor(int indexColor)
426
           {
427
                   int r,g,b;
428
                   // System.err.println("indexcolor = " + indexColor);
429
                   // Si no hay tabla de colores, interpretamos que todas las cosas son negras
430
                   if (m_colorTable == null) return new Color(0,0,0);
431

432
                   r = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][0]);
433
                   g = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][1]);
434
                   b = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][2]);
435

436
                   if ((r==255) && (g==255) & (b==255))
437
                   {
438
                           r=g=b=0; // El color blanco lo devolvemos como negro.
439
                   }
440

441
                   return new Color(r,g,b);
442
           } */
443

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

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

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

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

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

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

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

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

    
498
                return TRUE;
499
        }
500

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

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

    
526
                        FileChannel fc = fin.getChannel();
527

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

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

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

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

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

    
549
                                info.has_spatial_filter = FALSE;
550
                                info.sf_converted_to_uor = FALSE;
551
                                info.select_complex_group = FALSE;
552
                                info.in_complex_group = FALSE;
553
                        }
554
                }catch (FileNotFoundException e) {
555
                        throw new org.gvsig.data.datastores.vectorial.driver.exception.FileNotFoundDriverException("File not found",e);
556
                } catch (Exception e) {
557
                        throw new ReadException("DGNReader error",e);
558
                }
559

    
560
                return info;
561
        }
562

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

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

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

    
591
                return TRUE;
592
        }
593

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

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

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

    
621

    
622
                                //info.temporal[i]=input.readByte();
623
                        }
624

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

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

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

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

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

    
662
                        return FALSE;
663
                }
664

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

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

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

    
677
                return TRUE;
678
        }
679

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

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

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

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

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

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

    
710
                info.sf_converted_to_uor = TRUE;
711
        }
712

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

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

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

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

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

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

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

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

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

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

    
785
                return elemento;
786
        }
787

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
902
                                break;
903

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

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

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

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

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

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

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

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

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

    
1007
                        break;
1008

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

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

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

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

    
1051
                                elemento = psCell;
1052
                        }
1053

    
1054
                        break;
1055

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

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

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

    
1098
                        break;
1099

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

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

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

    
1119
                                        return null;
1120
                                }
1121

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

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

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

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

    
1144
                                elemento = psLine;
1145
                        }
1146

    
1147
                        break;
1148

    
1149
                        case DGNFileHeader.DGNT_GROUP_DATA:
1150

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1231
                        break;
1232

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

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

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

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

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

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

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

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

    
1280
                                psEllipse.secondary_axis *= info.scale;
1281

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

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

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

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

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

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

    
1322
                        break;
1323

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

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

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

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

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

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

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

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

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

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

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

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

    
1388
                                elemento = psText;
1389
                        }
1390

    
1391
                        break;
1392

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

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

    
1406
                                psHdr.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
1407
                                DGNParseCore(info, psHdr);
1408

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

    
1416
                        break;
1417

    
1418
                        case DGNFileHeader.DGNT_TAG_VALUE: {
1419
                                DGNElemTagValue psTag = new DGNElemTagValue();
1420

    
1421
                                psTag.stype = DGNFileHeader.DGNST_TAG_VALUE;
1422
                                DGNParseCore(info, psTag);
1423

    
1424
                                int[] fin = new int[1];
1425
                                fin[0] = 0;
1426

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

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

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

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

    
1461
                                elemento = psTag;
1462
                        }
1463

    
1464
                        break;
1465

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

    
1480
                        break;
1481
                }
1482

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

    
1492
                        elemento.raw_data = new byte[elemento.raw_bytes];
1493

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

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

    
1505
                elemento.offset = info.ftall - info.nElemBytes;
1506
                elemento.size = info.nElemBytes;
1507

    
1508
                // DGNDumpElement(info, elemento,"");
1509
                return elemento;
1510
        }
1511

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

    
1524
                return DGNParseIEEE(temp);
1525
        }
1526

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

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

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

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

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

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

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

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

    
1588
                lo = lo >> 3;
1589
                lo = (lo & 0x1fffffff) | (hi << 29);
1590

    
1591
                if (rndbits != 0) {
1592
                        lo = lo | 0x00000001;
1593
                }
1594

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

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

    
1616
                f[0] = 0;
1617

    
1618
                value = ByteUtils.bytesToDouble(result, f);
1619

    
1620
                return value;
1621
        }
1622

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1789
                ////System.out.println("dbl=  " + dbl);
1790
        }
1791

    
1792
        /************************************************************************/
1793
        /*                       DGNElemTypeHasDispHdr()                        */
1794
        /************************************************************************/
1795

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

    
1820
                        default:
1821
                                return TRUE;
1822
                }
1823
        }
1824

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

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

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

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

    
1850
                        byte aux = psData[35];
1851

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

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

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

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

    
1872
                        int numBytes = info.nElemBytes - (nAttIndex * 2) - 32;
1873

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

    
1879
                                elemento.attr_data = new byte[elemento.attr_bytes];
1880

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

    
1887
                return TRUE;
1888
        }
1889

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

    
1903
                while (rad50 > 0) {
1904
                        value = rad50;
1905
                        cTimes = 0;
1906

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

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

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

    
1934
                        str[i] = ch;
1935
                        i++;
1936

    
1937
                        temp = 1;
1938

    
1939
                        while (cTimes-- > 0)
1940
                                temp *= 40;
1941

    
1942
                        rad50 -= (value * temp);
1943
                }
1944

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

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

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

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

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

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

    
1977
                psColorTable.stype = DGNFileHeader.DGNST_COLORTABLE;
1978

    
1979
                DGNParseCore(psDGN, psColorTable);
1980

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

    
1984
                int[] fin = new int[1];
1985
                fin[0] = 0;
1986

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

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

    
1994
                int k = 0;
1995

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

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

    
2006
                if (psDGN.got_color_table == FALSE) {
2007
                        psDGN.color_table = psColorTable.color_info;
2008

    
2009
                        psDGN.got_color_table = 1;
2010
                }
2011

    
2012
                return psColorTable;
2013
        }
2014

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

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

    
2035
                // psTCB.dimension = 3;
2036
                fin[0] = 0;
2037

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

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

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

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

    
2053
                /* Get global origin */
2054
                System.arraycopy(psDGN.abyElem, 1240, temp1, 0, 8);
2055
                ByteBuffer buffer = ByteBuffer.wrap(psDGN.abyElem);
2056
                buffer.order(ByteOrder.LITTLE_ENDIAN);
2057
                psTCB.origin_x = buffer.getDouble(1240);
2058
                psTCB.origin_y = buffer.getDouble(1248);
2059
                psTCB.origin_z = buffer.getDouble(1256);
2060

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

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

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

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

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

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

    
2106
                        byte[] temp2 = new byte[4];
2107
                        int f = 0;
2108

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

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

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

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

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

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

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

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

    
2149
                                //nuevo m?todo
2150
                        }
2151

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

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

    
2164
                // DGNDumpElement(psDGN, psTCB,"");
2165
                return psTCB;
2166
        }
2167

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

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

    
2193
                if (pszString == null) {
2194
                        pszString[0] = ' ';
2195
                }
2196

    
2197
                pszReturn = new char[pszString.length];
2198

    
2199
                //pszReturn = VSIStrdup( pszString );
2200
                pszReturn = pszString;
2201

    
2202
                if (pszReturn == null) {
2203
                        System.out.println("error");
2204

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

    
2211
                return (pszReturn);
2212
        }
2213

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

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

    
2231
                DGNParseCore(psDGN, psTagSet);
2232

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

    
2241
                int[] fin = new int[1];
2242
                fin[0] = 0;
2243

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

    
2247
                psTagSet.tagSetName = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2248
                                                                                                 .toCharArray());
2249

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

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

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

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

    
2273
                        //= psTagSet.tagList + iTag;
2274
                        tagDef.id = iTag;
2275

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

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

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

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

    
2303
                        /* skip five zeros */
2304
                        nDataOffset += 5;
2305

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

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

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

    
2335
                return psTagSet;
2336
        }
2337

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

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

    
2363
                        return;
2364
                }
2365

    
2366
                psDGN.has_spatial_filter = TRUE;
2367
                psDGN.sf_converted_to_uor = FALSE;
2368

    
2369
                psDGN.sf_min_x_geo = dfXMin;
2370
                psDGN.sf_min_y_geo = dfYMin;
2371
                psDGN.sf_max_x_geo = dfXMax;
2372
                psDGN.sf_max_y_geo = dfYMax;
2373

    
2374
                DGNSpatialFilterToUOR(psDGN);
2375
        }
2376

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

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

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

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

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

    
2405
                if (psElement.properties != 0) {
2406
                        int nClass;
2407

    
2408
                        System.out.println("  properties=" + psElement.properties);
2409

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

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

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

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

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

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

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

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

    
2442
                        nClass = psElement.properties & DGNFileHeader.DGNPF_CLASS;
2443

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

    
2458
                        // System.out.println("\n");
2459
                }
2460

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

    
2466
                                int i;
2467

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

    
2473
                        break;
2474

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

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

    
2493
                        break;
2494

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

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

    
2507
                        break;
2508

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

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

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

    
2529
                        break;
2530

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

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

    
2543
                        break;
2544

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

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

    
2553
                        break;
2554

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

    
2559
                                int i;
2560

    
2561
                                System.out.println("  screen_flag:" + psCT.screen_flag + "\n");
2562

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

    
2570
                        break;
2571

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

    
2576
                                int iView;
2577

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

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

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

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

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

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

    
2618
                        break;
2619

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

    
2624
                                int iTag;
2625

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

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

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

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

    
2653
                        break;
2654

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

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

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

    
2674
                        break;
2675

    
2676
                        case DGNFileHeader.DGNST_GROUP_DATA: {
2677
                                // TODO
2678
                        }
2679

    
2680
                        break;
2681

    
2682
                        default:
2683
                                break;
2684
                }
2685

    
2686
                if (psElement.attr_bytes > 0) {
2687
                        int iLink;
2688

    
2689
                        System.out.println("Attributes:" + psElement.attr_bytes + "\n");
2690

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

    
2700
                                byte[] pabyData;
2701

    
2702
                                pabyData = DGNGetLinkage(psInfo, psElement, iLink, nLinkType,
2703
                                                nEntityNum, nMSLink, nLinkSize);
2704

    
2705
                                if (pabyData == null) {
2706
                                        break;
2707
                                }
2708

    
2709
                                System.out.println("Type=0x" + nLinkType);
2710

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

    
2716
                                System.out.println("\n  0x");
2717

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

    
2721
                                System.out.println("\n");
2722
                        }
2723
                }
2724
        }
2725

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

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

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

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

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

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

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

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

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

    
2815
                                return temp;
2816
                        }
2817
                }
2818

    
2819
                return null;
2820
        }
2821

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

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

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

    
2850
                /* unknown */
2851
                return 0;
2852
        }
2853

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

    
2867
                        case DGNFileHeader.DGNT_CELL_HEADER:
2868
                                return "Cell Header";
2869

    
2870
                        case DGNFileHeader.DGNT_LINE:
2871
                                return "Line";
2872

    
2873
                        case DGNFileHeader.DGNT_LINE_STRING:
2874
                                return "Line String";
2875

    
2876
                        case DGNFileHeader.DGNT_GROUP_DATA:
2877
                                return "Group Data";
2878

    
2879
                        case DGNFileHeader.DGNT_SHAPE:
2880
                                return "Shape";
2881

    
2882
                        case DGNFileHeader.DGNT_TEXT_NODE:
2883
                                return "Text Node";
2884

    
2885
                        case DGNFileHeader.DGNT_DIGITIZER_SETUP:
2886
                                return "Digitizer Setup";
2887

    
2888
                        case DGNFileHeader.DGNT_TCB:
2889
                                return "TCB";
2890

    
2891
                        case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
2892
                                return "Level Symbology";
2893

    
2894
                        case DGNFileHeader.DGNT_CURVE:
2895
                                return "Curve";
2896

    
2897
                        case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
2898
                                return "Complex Chain Header";
2899

    
2900
                        case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
2901
                                return "Complex Shape Header";
2902

    
2903
                        case DGNFileHeader.DGNT_ELLIPSE:
2904
                                return "Ellipse";
2905

    
2906
                        case DGNFileHeader.DGNT_ARC:
2907
                                return "Arc";
2908

    
2909
                        case DGNFileHeader.DGNT_TEXT:
2910
                                return "Text";
2911

    
2912
                        case DGNFileHeader.DGNT_BSPLINE:
2913
                                return "B-Spline";
2914

    
2915
                        case DGNFileHeader.DGNT_APPLICATION_ELEM:
2916
                                return "Application Element";
2917

    
2918
                        case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
2919
                                return "Shared Cell Definition";
2920

    
2921
                        case DGNFileHeader.DGNT_SHARED_CELL_ELEM:
2922
                                return "Shared Cell Element";
2923

    
2924
                        case DGNFileHeader.DGNT_TAG_VALUE:
2925
                                return "Tag Value";
2926

    
2927
                        default:
2928
                                System.out.println(nType);
2929

    
2930
                                return "Fallo";
2931
                }
2932
        }
2933

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

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

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

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

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

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

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

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

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

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

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

    
2998
                                char[] tempchar = new char[16];
2999

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

    
3004
                                //System.out.println(String.copyValueOf(tempchar));
3005
                        }
3006

    
3007
                        iChar++;
3008
                }
3009
        }
3010

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

    
3024
                DGNBuildIndex(psDGN);
3025

    
3026
                if (psDGN.got_bounds == FALSE) {
3027
                        return FALSE;
3028
                }
3029

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

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

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

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

    
3050
                sMin.x = minX - 2147483648.0;
3051
                sMin.y = minY - 2147483648.0;
3052
                sMin.z = minZ - 2147483648.0;
3053

    
3054
                DGNTransformPoint(psDGN, sMin);
3055

    
3056
                padfExtents[0] = sMin.x;
3057
                padfExtents[1] = sMin.y;
3058
                padfExtents[2] = sMin.z;
3059

    
3060
                double maxX = psDGN.max_x;
3061
                double maxY = psDGN.max_y;
3062
                double maxZ = psDGN.max_z;
3063

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

    
3068
                        //System.out.println("maxX"+maxX);
3069
                }
3070

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

    
3074
                        //System.out.println("maxY"+maxY);
3075
                }
3076

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

    
3081
                sMax.x = maxX - 2147483648.0;
3082
                sMax.y = maxY - 2147483648.0;
3083
                sMax.z = maxZ - 2147483648.0;
3084

    
3085
                DGNTransformPoint(psDGN, sMax);
3086

    
3087
                padfExtents[3] = sMax.x;
3088
                padfExtents[4] = sMax.y;
3089
                padfExtents[5] = sMax.z;
3090

    
3091
                return TRUE;
3092
        }
3093

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

    
3106
                if (psDGN.index_built != FALSE) {
3107
                        return;
3108
                }
3109

    
3110
                psDGN.index_built = TRUE;
3111

    
3112
                //DGNRewind( psDGN );
3113
                nMaxElements = 0;
3114

    
3115
                //nLastOffset = VSIFTell( psDGN.fp );
3116
                nLastOffset = bb.position(); //psDGN.ftall;
3117

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

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

    
3125
                                DGNElementInfo[] nuevo = new DGNElementInfo[nMaxElements];
3126

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

    
3130
                                psDGN.element_index = nuevo;
3131

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

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

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

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

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

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

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

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

    
3192
                        //DGNInfo tempo = new DGNInfo();
3193
                        double[] anRegion;
3194

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

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

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

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

    
3235
                        psDGN.element_count++;
3236

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

    
3241
                //DGNRewind( psDGN );
3242
                psDGN.max_element_count = nMaxElements;
3243
        }
3244

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

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

    
3281
                if (bResult == null) {
3282
                        return FALSE;
3283
                }
3284

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

    
3293
                psMax.x = tempo.max_x - 2147483648.0;
3294
                psMax.y = tempo.max_y - 2147483648.0;
3295
                psMax.z = tempo.max_z - 2147483648.0;
3296

    
3297
                DGNTransformPoint(psDGN, psMin);
3298
                DGNTransformPoint(psDGN, psMax);
3299

    
3300
                return TRUE;
3301
        }
3302

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

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

    
3320
                return psDGN.element_index;
3321
        }
3322

    
3323
        /************************************************************************/
3324
        /*                           DGNLookupColor()                           */
3325
        /************************************************************************/
3326

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

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

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

    
3361
                return new Color(r, g, b);
3362
        }
3363

    
3364
        /************************************************************************/
3365
        /*                        DGNGetShapeFillInfo()                         */
3366
        /************************************************************************/
3367

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

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

    
3391
                        byte[] pabyData;
3392

    
3393
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3394
                                        nEntityNum, nMSLink, nLinkSize);
3395

    
3396
                        if (pabyData == null) {
3397
                                return -1;
3398
                        }
3399

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

    
3404
                                break;
3405
                        }
3406
                }
3407

    
3408
                return color_index;
3409
        }
3410

    
3411
        /************************************************************************/
3412
        /*                        DGNGetAssocID()                               */
3413
        /************************************************************************/
3414

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

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

    
3437
                        byte[] pabyData;
3438

    
3439
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3440
                                        nEntityNum, nMSLink, nLinkSize);
3441

    
3442
                        if (pabyData == null) {
3443
                                return -1;
3444
                        }
3445

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