Statistics
| Revision:

root / org.gvsig.dgn / trunk / org.gvsig.dgn / org.gvsig.dgn.provider / src / main / java / org / gvsig / fmap / dal / store / dgn / lib / DGNReader.java @ 6

History | View | Annotate | Download (97.3 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.fmap.dal.store.dgn.lib;
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
import java.text.MessageFormat;
58

    
59
import org.gvsig.fmap.dal.exception.DataException;
60
import org.gvsig.fmap.dal.exception.ReadException;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

    
64
/**
65
 * Clase dedicada a leer del fichero DGN.
66
 * 
67
 * @author FJP
68
 */
69
public class DGNReader {
70
        private static Logger logger = LoggerFactory.getLogger(DGNReader.class);
71
        static int[][] abyDefaultPCT = { { 255, 255, 255 }, { 0, 0, 255 },
72
                        { 0, 255, 0 }, { 255, 0, 0 }, { 255, 255, 0 }, { 255, 0, 255 },
73
                        { 255, 127, 0 }, { 0, 255, 255 }, { 64, 64, 64 },
74
                        { 192, 192, 192 }, { 254, 0, 96 }, { 160, 224, 0 },
75
                        { 0, 254, 160 }, { 128, 0, 160 }, { 176, 176, 176 },
76
                        { 0, 240, 240 }, { 240, 240, 240 }, { 0, 0, 240 }, { 0, 240, 0 },
77
                        { 240, 0, 0 }, { 240, 240, 0 }, { 240, 0, 240 }, { 240, 122, 0 },
78
                        { 0, 240, 240 }, { 240, 240, 240 }, { 0, 0, 240 }, { 0, 240, 0 },
79
                        { 240, 0, 0 }, { 240, 240, 0 }, { 240, 0, 240 }, { 240, 122, 0 },
80
                        { 0, 225, 225 }, { 225, 225, 225 }, { 0, 0, 225 }, { 0, 225, 0 },
81
                        { 225, 0, 0 }, { 225, 225, 0 }, { 225, 0, 225 }, { 225, 117, 0 },
82
                        { 0, 225, 225 }, { 225, 225, 225 }, { 0, 0, 225 }, { 0, 225, 0 },
83
                        { 225, 0, 0 }, { 225, 225, 0 }, { 225, 0, 225 }, { 225, 117, 0 },
84
                        { 0, 210, 210 }, { 210, 210, 210 }, { 0, 0, 210 }, { 0, 210, 0 },
85
                        { 210, 0, 0 }, { 210, 210, 0 }, { 210, 0, 210 }, { 210, 112, 0 },
86
                        { 0, 210, 210 }, { 210, 210, 210 }, { 0, 0, 210 }, { 0, 210, 0 },
87
                        { 210, 0, 0 }, { 210, 210, 0 }, { 210, 0, 210 }, { 210, 112, 0 },
88
                        { 0, 195, 195 }, { 195, 195, 195 }, { 0, 0, 195 }, { 0, 195, 0 },
89
                        { 195, 0, 0 }, { 195, 195, 0 }, { 195, 0, 195 }, { 195, 107, 0 },
90
                        { 0, 195, 195 }, { 195, 195, 195 }, { 0, 0, 195 }, { 0, 195, 0 },
91
                        { 195, 0, 0 }, { 195, 195, 0 }, { 195, 0, 195 }, { 195, 107, 0 },
92
                        { 0, 180, 180 }, { 180, 180, 180 }, { 0, 0, 180 }, { 0, 180, 0 },
93
                        { 180, 0, 0 }, { 180, 180, 0 }, { 180, 0, 180 }, { 180, 102, 0 },
94
                        { 0, 180, 180 }, { 180, 180, 180 }, { 0, 0, 180 }, { 0, 180, 0 },
95
                        { 180, 0, 0 }, { 180, 180, 0 }, { 180, 0, 180 }, { 180, 102, 0 },
96
                        { 0, 165, 165 }, { 165, 165, 165 }, { 0, 0, 165 }, { 0, 165, 0 },
97
                        { 165, 0, 0 }, { 165, 165, 0 }, { 165, 0, 165 }, { 165, 97, 0 },
98
                        { 0, 165, 165 }, { 165, 165, 165 }, { 0, 0, 165 }, { 0, 165, 0 },
99
                        { 165, 0, 0 }, { 165, 165, 0 }, { 165, 0, 165 }, { 165, 97, 0 },
100
                        { 0, 150, 150 }, { 150, 150, 150 }, { 0, 0, 150 }, { 0, 150, 0 },
101
                        { 150, 0, 0 }, { 150, 150, 0 }, { 150, 0, 150 }, { 150, 92, 0 },
102
                        { 0, 150, 150 }, { 150, 150, 150 }, { 0, 0, 150 }, { 0, 150, 0 },
103
                        { 150, 0, 0 }, { 150, 150, 0 }, { 150, 0, 150 }, { 150, 92, 0 },
104
                        { 0, 135, 135 }, { 135, 135, 135 }, { 0, 0, 135 }, { 0, 135, 0 },
105
                        { 135, 0, 0 }, { 135, 135, 0 }, { 135, 0, 135 }, { 135, 87, 0 },
106
                        { 0, 135, 135 }, { 135, 135, 135 }, { 0, 0, 135 }, { 0, 135, 0 },
107
                        { 135, 0, 0 }, { 135, 135, 0 }, { 135, 0, 135 }, { 135, 87, 0 },
108
                        { 0, 120, 120 }, { 120, 120, 120 }, { 0, 0, 120 }, { 0, 120, 0 },
109
                        { 120, 0, 0 }, { 120, 120, 0 }, { 120, 0, 120 }, { 120, 82, 0 },
110
                        { 0, 120, 120 }, { 120, 120, 120 }, { 0, 0, 120 }, { 0, 120, 0 },
111
                        { 120, 0, 0 }, { 120, 120, 0 }, { 120, 0, 120 }, { 120, 82, 0 },
112
                        { 0, 105, 105 }, { 105, 105, 105 }, { 0, 0, 105 }, { 0, 105, 0 },
113
                        { 105, 0, 0 }, { 105, 105, 0 }, { 105, 0, 105 }, { 105, 77, 0 },
114
                        { 0, 105, 105 }, { 105, 105, 105 }, { 0, 0, 105 }, { 0, 105, 0 },
115
                        { 105, 0, 0 }, { 105, 105, 0 }, { 105, 0, 105 }, { 105, 77, 0 },
116
                        { 0, 90, 90 }, { 90, 90, 90 }, { 0, 0, 90 }, { 0, 90, 0 },
117
                        { 90, 0, 0 }, { 90, 90, 0 }, { 90, 0, 90 }, { 90, 72, 0 },
118
                        { 0, 90, 90 }, { 90, 90, 90 }, { 0, 0, 90 }, { 0, 90, 0 },
119
                        { 90, 0, 0 }, { 90, 90, 0 }, { 90, 0, 90 }, { 90, 72, 0 },
120
                        { 0, 75, 75 }, { 75, 75, 75 }, { 0, 0, 75 }, { 0, 75, 0 },
121
                        { 75, 0, 0 }, { 75, 75, 0 }, { 75, 0, 75 }, { 75, 67, 0 },
122
                        { 0, 75, 75 }, { 75, 75, 75 }, { 0, 0, 75 }, { 0, 75, 0 },
123
                        { 75, 0, 0 }, { 75, 75, 0 }, { 75, 0, 75 }, { 75, 67, 0 },
124
                        { 0, 60, 60 }, { 60, 60, 60 }, { 0, 0, 60 }, { 0, 60, 0 },
125
                        { 60, 0, 0 }, { 60, 60, 0 }, { 60, 0, 60 }, { 60, 62, 0 },
126
                        { 0, 60, 60 }, { 60, 60, 60 }, { 0, 0, 60 }, { 0, 60, 0 },
127
                        { 60, 0, 0 }, { 60, 60, 0 }, { 60, 0, 60 }, { 60, 62, 0 },
128
                        { 0, 45, 45 }, { 45, 45, 45 }, { 0, 0, 45 }, { 0, 45, 0 },
129
                        { 45, 0, 0 }, { 45, 45, 0 }, { 45, 0, 45 }, { 45, 57, 0 },
130
                        { 0, 45, 45 }, { 45, 45, 45 }, { 0, 0, 45 }, { 0, 45, 0 },
131
                        { 45, 0, 0 }, { 45, 45, 0 }, { 45, 0, 45 }, { 45, 57, 0 },
132
                        { 0, 30, 30 }, { 30, 30, 30 }, { 0, 0, 30 }, { 0, 30, 0 },
133
                        { 30, 0, 0 }, { 30, 30, 0 }, { 30, 0, 30 }, { 30, 52, 0 },
134
                        { 0, 30, 30 }, { 30, 30, 30 }, { 0, 0, 30 }, { 0, 30, 0 },
135
                        { 30, 0, 0 }, { 30, 30, 0 }, { 30, 0, 30 }, { 192, 192, 192 },
136
                        { 28, 0, 100 } };
137
        private int LSB;
138
        private FileInputStream fin;
139

    
140
        // private LEDataInputStream input;
141
        private MappedByteBuffer bb;
142
        private int FALSE = 0;
143
        private int TRUE = 1;
144
        private DGNElemCore elemento;
145
        private DGNInfo info; // Contiene el path y otras cosas
146
        private Rectangle2D.Double m_BoundingBox;
147
        private DGNElemColorTable m_colorTable;
148

    
149
        /**
150
         * Crea un nuevo DGNReader.
151
         * 
152
         * @param pathFich
153
         *            DOCUMENT ME!
154
         */
155
        public DGNReader(String pathFich) throws DataException {
156
                info = new DGNInfo();
157

    
158
                DGNElemCore elemento = new DGNElemCore();
159
                int iArg;
160
                int bReportExtents = 0;
161
                byte[] achRaw = new byte[64];
162
                achRaw[63] = 1;
163

    
164
                double dfSFXMin = 0.0;
165
                double dfSFXMax = 0.0;
166
                double dfSFYMin = 0.0;
167
                double dfSFYMax = 0.0;
168

    
169
                info.fp = pathFich;
170
                info = DGNOpen(info, 0);
171

    
172
                bb.rewind();
173
                DGNSetSpatialFilter(info, dfSFXMin, dfSFYMin, dfSFXMax, dfSFYMax);
174

    
175
                int nLevel;
176
                int nType;
177
                int[] anLevelTypeCount = new int[128 * 64];
178
                int[] anLevelCount = new int[64];
179
                int[] anTypeCount = new int[128];
180
                double[] adfExtents = new double[6];
181
                int[] nCount = new int[1];
182
                nCount[0] = 0;
183

    
184
                DGNGetExtents(info, adfExtents); // extender
185
                System.out.println("X Range:" + adfExtents[0] + ", " + adfExtents[3]);
186
                System.out.println("Y Range:" + adfExtents[1] + ", " + adfExtents[4]);
187
                System.out.println("Z Range:" + adfExtents[2] + ", " + adfExtents[5]);
188

    
189
                m_BoundingBox = new Rectangle2D.Double();
190
                m_BoundingBox.setRect(adfExtents[0], adfExtents[1],
191
                                (adfExtents[3] - adfExtents[0]),
192
                                (adfExtents[4] - adfExtents[1]));
193

    
194
                /* m_Renderer = new FRenderer(this); */
195
                DGNElementInfo[] pasEI; // =new DGNElementInfo[nCount+1];
196
                pasEI = DGNGetElementIndex(info, nCount);
197

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

    
200
                for (int i = 0; i < nCount[0]; i++) {
201
                        anLevelTypeCount[(pasEI[i].level * 128) + pasEI[i].type]++;
202
                        anLevelCount[pasEI[i].level]++;
203
                        anTypeCount[pasEI[i].type]++;
204
                }
205

    
206
                // //System.out.println("\n");
207
                System.out.println("Per Type Report\n");
208
                System.out.println("===============\n");
209

    
210
                for (nType = 0; nType < 128; nType++) {
211
                        if (anTypeCount[nType] != 0) {
212
                                System.out.println("Type:" + DGNTypeToName(nType) + ":"
213
                                                + anTypeCount[nType] + "\n");
214
                        }
215
                }
216

    
217
                // System.out.println("\n");
218
                // System.out.println("Per Level Report\n");
219
                // System.out.println("================\n");
220
                for (nLevel = 0; nLevel < 64; nLevel++) {
221
                        if (anLevelCount[nLevel] == 0) {
222
                                continue;
223
                        }
224

    
225
                        // System.out.println("Level " + nLevel + "," + anLevelCount[nLevel]
226
                        // +"elements:\n");
227
                        for (nType = 0; nType < 128; nType++) {
228
                                if (anLevelTypeCount[(nLevel * 128) + nType] != 0) {
229
                                        // System.out.println("  Type " + DGNTypeToName(nType) +
230
                                        // ","anLevelTypeCount[(nLevel * 128) + nType] + "\n");
231
                                }
232
                        }
233

    
234
                        // System.out.println("\n");
235
                }
236

    
237
                bb.rewind();
238
        }
239

    
240
        /*
241
         * public Color getColor(int indexColor) { int r,g,b; //
242
         * System.err.println("indexcolor = " + indexColor); // Si no hay tabla de
243
         * colores, interpretamos que todas las cosas son negras if (m_colorTable ==
244
         * null) return new Color(0,0,0);
245
         * 
246
         * r = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][0]); g =
247
         * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][1]); b =
248
         * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][2]);
249
         * 
250
         * if ((r==255) && (g==255) & (b==255)) { r=g=b=0; // El color blanco lo
251
         * devolvemos como negro. }
252
         * 
253
         * return new Color(r,g,b); }
254
         */
255

    
256
        /**
257
         * Devuelve la informaci?n del DGN.
258
         * 
259
         * @return DGNInfo Informaci?n.
260
         */
261
        public DGNInfo getInfo() {
262
                return info;
263
        }
264

    
265
        /**
266
         * Devuelve el n?mero de elementos.
267
         * 
268
         * @return N?mero de elementos.
269
         */
270
        public int getNumEntities() {
271
                return info.element_count;
272
        }
273

    
274
        /**
275
         * Devuelve el rect?ngulo del extent.
276
         * 
277
         * @return Rect?ngulo.
278
         */
279
        public Rectangle2D getBoundingBox() {
280
                return m_BoundingBox;
281
        }
282

    
283
        /************************************************************************/
284
        /* DGNGotoElement() */
285
        /************************************************************************/
286

    
287
        /**
288
         * Seek to indicated element. Changes what element will be read on the next
289
         * call to DGNReadElement(). Note that this function requires and index, and
290
         * one will be built if not already available.
291
         * 
292
         * @param element_id
293
         *            the element to seek to. These values are sequentially ordered
294
         *            starting at zero for the first element.
295
         * 
296
         * @return returns TRUE on success or FALSE on failure.
297
         */
298
        public int DGNGotoElement(int element_id) {
299
                DGNBuildIndex(info);
300

    
301
                if ((element_id < 0) || (element_id >= info.element_count)) {
302
                        return FALSE;
303
                }
304

    
305
                // System.out.println("Posicionamos en " +
306
                // info.element_index[element_id].offset);
307
                bb.position((int) info.element_index[element_id].offset);
308

    
309
                info.next_element_id = element_id;
310
                info.in_complex_group = FALSE;
311

    
312
                return TRUE;
313
        }
314

    
315
        /**
316
         * DGNOpen
317
         * 
318
         * @param info
319
         *            DOCUMENT ME!
320
         * @param bUpdate
321
         *            DOCUMENT ME!
322
         * 
323
         * @return DOCUMENT ME!
324
         */
325
        private DGNInfo DGNOpen(DGNInfo info, int bUpdate) throws DataException {
326
                int pos = 0;
327
                byte[] abyHeader = new byte[512];
328
                info.next_element_id = 0;
329
                info.got_tcb = FALSE;
330
                info.scale = 1.0;
331
                info.origin_x = 0.0;
332
                info.origin_y = 0.0;
333
                info.origin_z = 0.0;
334
                info.index_built = FALSE;
335
                info.element_count = 0;
336
                info.element_index = null;
337
                info.got_bounds = FALSE;
338

    
339
                try {
340
                        fin = new FileInputStream(info.fp);
341

    
342
                        FileChannel fc = fin.getChannel();
343

    
344
                        long sz = fc.size();
345
                        int numReg;
346

    
347
                        // Get the file's size and then map it into memory
348
                        bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
349
                        bb.order(ByteOrder.nativeOrder());
350
                        bb.get(abyHeader, pos, abyHeader.length);
351

    
352
                        info.ftall = (int) (sz / 16);
353

    
354
                        if (bb.order() == ByteOrder.LITTLE_ENDIAN) {
355
                                LSB = TRUE;
356
                        }
357

    
358
                        if (DGNTestOpen(abyHeader, abyHeader.length) != FALSE) {
359
                                if (abyHeader[0] == (byte) 0xC8) {
360
                                        info.dimension = 3; // 0xC8
361
                                } else {
362
                                        info.dimension = 2;
363
                                }
364

    
365
                                info.has_spatial_filter = FALSE;
366
                                info.sf_converted_to_uor = FALSE;
367
                                info.select_complex_group = FALSE;
368
                                info.in_complex_group = FALSE;
369
                        }
370
                } catch (FileNotFoundException e) {
371
                        throw new org.gvsig.fmap.dal.exception.FileNotFoundException(
372
                                        info.fp);
373
                } catch (Exception e) {
374
                        throw new ReadException("DGNReader error", e);
375
                }
376

    
377
                return info;
378
        }
379

    
380
        /**
381
         * Comprobaci?n si se puede abrir el fichero.
382
         * 
383
         * @param pabyHeader
384
         *            Vector byte con el header.
385
         * @param nByteCount
386
         *            n?mero de bytes.
387
         * 
388
         * @return Devuelve un enteor que muestra si no hay errores.
389
         */
390
        private int DGNTestOpen(byte[] pabyHeader, int nByteCount) {
391
                if (nByteCount < 4) {
392
                        return TRUE;
393
                }
394

    
395
                // Is it a cell library?
396
                if ((pabyHeader[0] == (byte) 0x08) && (pabyHeader[1] == (byte) 0x05)
397
                                && (pabyHeader[2] == (byte) 0x17)
398
                                && (pabyHeader[3] == (byte) 0x00)) {
399
                        return TRUE;
400
                }
401

    
402
                // Is it not a regular 2D or 3D file?
403
                if (((pabyHeader[0] != (byte) 0x08) && (pabyHeader[0] != (byte) 0xC8))
404
                                || (pabyHeader[1] != (byte) 0x09)
405
                                || (pabyHeader[2] != (byte) 0xFE)
406
                                || (pabyHeader[3] != (byte) 0x02)) {
407
                        return FALSE;
408
                }
409

    
410
                return TRUE;
411
        }
412

    
413
        /**
414
         * Lee una fila del elemento.
415
         * 
416
         * @param info
417
         *            Informaci?n del DGN.
418
         * @param core
419
         *            Elemento.
420
         * 
421
         * @return Devuelve un entero que muestra si se ha calculado correctamente.
422
         */
423
        private int DGNLoadRawElement(DGNInfo info, DGNElemCore core) {
424
                /* -------------------------------------------------------------------- */
425
                /* Read the first four bytes to get the level, type, and word */
426
                /* count. */
427
                /* -------------------------------------------------------------------- */
428

    
429
                // int nType, nWords, nLevel;
430
                int nType = 0;
431
                int nWords = 0;
432
                int nLevel = 0;
433
                int bytesCount = 0;
434

    
435
                try {
436
                        // input=new LEDataInputStream(fin);
437
                        for (int i = 0; i < 4; i++) {
438
                                info.abyElem[i] = bb.get();
439
                                if (i == 1) {
440
                                        if ((info.abyElem[0] == -1) && (info.abyElem[1] == -1)) {
441
                                                return FALSE;
442
                                        }
443
                                }
444

    
445
                                // info.temporal[i]=input.readByte();
446
                        }
447

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

    
450
                        nWords = ByteUtils.byteToUnsignedInt(info.abyElem[2])
451
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[3]) * 256);
452
                        nType = ByteUtils.byteToUnsignedInt(info.abyElem[1]) & 0x7f;
453
                        nLevel = ByteUtils.byteToUnsignedInt(info.abyElem[0]) & 0x3f;
454

    
455
                        /*
456
                         * ------------------------------------------------------------------
457
                         * --
458
                         */
459
                        /* Read the rest of the element data into the working buffer. */
460
                        /*
461
                         * ------------------------------------------------------------------
462
                         * --
463
                         */
464
                        if (((nWords * 2) + 4) > info.abyElem.length) {
465
                                return FALSE;
466
                        }
467

    
468
                        // CPLAssert( nWords * 2 + 4 <= (int) sizeof(psDGN->abyElem) );
469
                        // byte[] temp = new byte[131072];
470
                        // //System.out.println(nWords);
471
                        for (; bytesCount < (nWords * 2) && bb.hasRemaining(); bytesCount++) {
472
                                info.abyElem[bytesCount + 4] = bb.get();
473
                        }
474

    
475
                        // input.close();
476
                        /*
477
                         * ------------------------------------------------------------------
478
                         * --
479
                         */
480
                        /* Read the rest of the element data into the working buffer. */
481
                        /*
482
                         * ------------------------------------------------------------------
483
                         * --
484
                         */
485
                        /*
486
                         * CPLAssert( nWords * 2 + 4 <= (int) sizeof(psDGN->abyElem) ); if(
487
                         * (int) VSIFRead( psDGN->abyElem + 4, 2, nWords, psDGN->fp ) !=
488
                         * nWords ) return FALSE;
489
                         */
490
                        info.ftall = bb.position();
491
                } catch (Exception e) {
492
                        logger.warn(MessageFormat.format("The DGN file {0} may not be loaded correctly.\n" +
493
                                        "Error loading:\n" +
494
                                        "nWords = {1}\n" +
495
                                        "info.next_element_id {2}\n" +
496
                                        "info.abyElem.length =  {3}\n" +
497
                                        "bb.position() =  {4}",
498
                                        info.fp,
499
                                        nWords,
500
                                        info.next_element_id,
501
                                        info.abyElem.length,
502
                                        bb.position()), e);
503

    
504
                        return FALSE;
505
                }
506

    
507
                // info.nElemBytes = (nWords * 2) + 4;
508
                info.nElemBytes = bytesCount + 4;
509
                info.next_element_id++;
510

    
511
                /* -------------------------------------------------------------------- */
512
                /* Return requested info. */
513
                /* -------------------------------------------------------------------- */
514
                // if( core.type != null )
515
                core.type = nType;
516

    
517
                // if( core.level != null )
518
                core.level = nLevel;
519

    
520
                return TRUE;
521
        }
522

    
523
        /**
524
         * Calcula el filtro espacial al rect?ngulo del elemento.
525
         * 
526
         * @param info
527
         *            Informaci?n del DGN.
528
         */
529
        private void DGNSpatialFilterToUOR(DGNInfo info) {
530
                DGNPoint sMin = new DGNPoint();
531
                DGNPoint sMax = new DGNPoint();
532

    
533
                if ((info.sf_converted_to_uor == 1)
534
                                || (!(info.has_spatial_filter == 1)) || (!(info.got_tcb == 1))) {
535
                        return;
536
                }
537

    
538
                sMin.x = info.sf_min_x_geo;
539
                sMin.y = info.sf_min_y_geo;
540
                sMin.z = 0;
541

    
542
                sMax.x = info.sf_max_x_geo;
543
                sMax.y = info.sf_max_y_geo;
544
                sMax.z = 0;
545

    
546
                DGNInverseTransformPoint(info, sMin);
547
                DGNInverseTransformPoint(info, sMax);
548

    
549
                info.sf_min_x = (long) (sMin.x + 2147483648.0);
550
                info.sf_min_y = (long) (sMin.y + 2147483648.0);
551
                info.sf_max_x = (long) (sMax.x + 2147483648.0);
552
                info.sf_max_y = (long) (sMax.y + 2147483648.0);
553

    
554
                info.sf_converted_to_uor = TRUE;
555
        }
556

    
557
        /**
558
         * Calcula un punto aplicandole la transformaci?n.
559
         * 
560
         * @param info
561
         *            Informaci?n del DGN.
562
         * @param punto
563
         *            Punto.
564
         */
565
        private void DGNInverseTransformPoint(DGNInfo info, DGNPoint punto) {
566
                punto.x = (punto.x + info.origin_x) / info.scale;
567
                punto.y = (punto.y + info.origin_y) / info.scale;
568
                punto.z = (punto.z + info.origin_z) / info.scale;
569

    
570
                punto.x = Math.max(-2147483647, Math.min(2147483647, punto.x));
571
                punto.y = Math.max(-2147483647, Math.min(2147483647, punto.y));
572
                punto.z = Math.max(-2147483647, Math.min(2147483647, punto.z));
573
        }
574

    
575
        /**
576
         * DOCUMENT ME!
577
         * 
578
         * @return DOCUMENT ME!
579
         */
580
        public DGNElemCore DGNReadElement() {
581
                DGNElemCore elemento = new DGNElemCore();
582
                int nType;
583
                int nLevel;
584
                int bInsideFilter;
585

    
586
                /* -------------------------------------------------------------------- */
587
                /* Load the element data into the current buffer. If a spatial */
588
                /* filter is in effect, loop until we get something within our */
589
                /* spatial constraints. */
590
                /* -------------------------------------------------------------------- */
591
                do {
592
                        bInsideFilter = TRUE;
593

    
594
                        int fin_fichero = DGNLoadRawElement(info, elemento);
595

    
596
                        if (fin_fichero == FALSE) {
597
                                return null;
598
                        }
599

    
600
                        if (info.has_spatial_filter != FALSE) {
601
                                // long nXMin, nXMax, nYMin, nYMax;
602
                                if (info.sf_converted_to_uor == FALSE) {
603
                                        DGNSpatialFilterToUOR(info);
604
                                }
605

    
606
                                if (DGNGetRawExtents(info, null, elemento) == null) {
607
                                        bInsideFilter = TRUE;
608
                                } else if ((info.min_x > info.sf_max_x)
609
                                                || (info.min_y > info.sf_max_y)
610
                                                || (info.max_x < info.sf_min_x)
611
                                                || (info.max_y < info.sf_min_y)) {
612
                                        bInsideFilter = FALSE;
613
                                }
614

    
615
                                if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)
616
                                                || (elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)) {
617
                                        info.in_complex_group = TRUE;
618
                                        info.select_complex_group = bInsideFilter;
619
                                } else if ((info.abyElem[0] & (byte) 0x80) != FALSE) {
620
                                        if (info.in_complex_group == TRUE) {
621
                                                bInsideFilter = info.select_complex_group;
622
                                        }
623
                                } else {
624
                                        info.in_complex_group = FALSE;
625
                                }
626
                        }
627
                } while (bInsideFilter == FALSE);
628

    
629
                elemento = DGNProcessElement(info, elemento.type, elemento.level);
630

    
631
                return elemento;
632
        }
633

    
634
        /**
635
         * Devuelve los extent de una fila.
636
         * 
637
         * @param info
638
         *            Informaci?n del DGN.
639
         * @param pabyRawData
640
         *            Vector de byte.
641
         * @param elemento
642
         *            Elemento.
643
         * 
644
         * @return Vector de double.
645
         */
646
        public double[] DGNGetRawExtents(DGNInfo info, byte[] pabyRawData,
647
                        DGNElemCore elemento) {
648
                // byte[] pabyRawData = new byte[info.abyElem.length];
649
                if (pabyRawData == null) {
650
                        pabyRawData = info.abyElem;
651
                }
652

    
653
                double[] tempo = new double[6];
654

    
655
                switch (elemento.type) {
656
                case DGNFileHeader.DGNT_LINE:
657
                case DGNFileHeader.DGNT_LINE_STRING:
658
                case DGNFileHeader.DGNT_SHAPE:
659
                case DGNFileHeader.DGNT_CURVE:
660
                case DGNFileHeader.DGNT_BSPLINE:
661
                case DGNFileHeader.DGNT_ELLIPSE:
662
                case DGNFileHeader.DGNT_ARC:
663
                case DGNFileHeader.DGNT_TEXT:
664
                case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
665
                case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
666

    
667
                        byte[] temp = new byte[4];
668
                        System.arraycopy(pabyRawData, 4, temp, 0, 4);
669
                        tempo[0] = DGN_INT32(temp); // 4
670

    
671
                        System.arraycopy(pabyRawData, 8, temp, 0, 4);
672
                        tempo[1] = DGN_INT32(temp);
673

    
674
                        System.arraycopy(pabyRawData, 12, temp, 0, 4);
675
                        tempo[2] = DGN_INT32(temp);
676

    
677
                        System.arraycopy(pabyRawData, 16, temp, 0, 4);
678
                        tempo[3] = DGN_INT32(temp);
679

    
680
                        System.arraycopy(pabyRawData, 20, temp, 0, 4);
681
                        tempo[4] = DGN_INT32(temp);
682

    
683
                        System.arraycopy(pabyRawData, 24, temp, 0, 4);
684
                        tempo[5] = DGN_INT32(temp);
685

    
686
                        // System.out.println("tempo = " + tempo[0] + " " + tempo[1] + " " +
687
                        // tempo[2]);
688
                        return tempo;
689

    
690
                default:
691
                        return null;
692
                }
693
        }
694

    
695
        /**
696
         * A partir de un vector de byte devuelve un double.
697
         * 
698
         * @param p
699
         *            Vector de byte.
700
         * 
701
         * @return double.
702
         */
703
        private double DGN_INT32(byte[] p) {
704
                int x = 256;
705
                int x0;
706
                int x1;
707
                int x2;
708
                int x3;
709
                x0 = p[0];
710
                x1 = p[1];
711
                x2 = p[2];
712
                x3 = p[3];
713

    
714
                if (p[0] < 0) {
715
                        x0 = x + p[0];
716
                }
717

    
718
                if (p[1] < 0) {
719
                        x1 = x + p[1];
720
                }
721

    
722
                if (p[2] < 0) {
723
                        x2 = x + p[2];
724
                }
725

    
726
                if (p[3] < 0) {
727
                        x3 = x + p[3];
728
                }
729

    
730
                return (x2 + (x3 * 256) + (x1 * 65536 * 256) + (x0 * 65536));
731
        }
732

    
733
        /**
734
         * DOCUMENT ME!
735
         * 
736
         * @param info
737
         *            DOCUMENT ME!
738
         * @param nType
739
         *            DOCUMENT ME!
740
         * @param nLevel
741
         *            DOCUMENT ME!
742
         * 
743
         * @return DOCUMENT ME!
744
         */
745
        private DGNElemCore DGNProcessElement(DGNInfo info, int nType, int nLevel) {
746
                DGNElemCore elemento = new DGNElemCore();
747

    
748
                // if (info.next_element_id < 100)
749
                // System.out.println("nType = " + nType);
750
                switch (nType) {
751
                case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
752
                        System.err.println(DGNTypeToName(nType));
753
                        elemento.stype = DGNFileHeader.DGNST_SHARED_CELL_DEFN;
754
                        DGNParseCore(info, elemento);
755

    
756
                        break;
757

    
758
                case DGNFileHeader.DGNT_CELL_HEADER: {
759
                        // System.err.println("DGNT_CELL_HEADER");
760
                        DGNElemCellHeader psCell = new DGNElemCellHeader();
761
                        psCell.stype = DGNFileHeader.DGNST_CELL_HEADER;
762
                        DGNParseCore(info, psCell);
763
                        psCell.totlength = ByteUtils.getUnsigned(info.abyElem[36])
764
                                        + (ByteUtils.getUnsigned(info.abyElem[37]) * 256);
765

    
766
                        byte[] temp = new byte[psCell.name.length];
767
                        System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
768
                        DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[38])
769
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256),
770
                                        temp);
771

    
772
                        System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length - 3); // esta
773
                                                                                                                                                                // linea
774
                                                                                                                                                                // puede
775
                                                                                                                                                                // tener
776
                                                                                                                                                                // problemas.
777
                        DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[40])
778
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256),
779
                                        temp);
780
                        psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
781
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
782
                        psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
783
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
784
                        psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
785
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
786
                        psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
787
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
788
                        psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
789
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
790
                        psCell.color = info.abyElem[35];
791

    
792
                        if (info.dimension == 2) {
793
                                byte[] temp1 = new byte[4];
794
                                System.arraycopy(info.abyElem, 52, temp1, 0, 4);
795
                                psCell.rnglow.x = DGN_INT32(temp1);
796
                                System.arraycopy(info.abyElem, 56, temp1, 0, 4);
797
                                psCell.rnglow.y = DGN_INT32(temp);
798
                                System.arraycopy(info.abyElem, 60, temp1, 0, 4);
799
                                psCell.rnghigh.x = DGN_INT32(temp1);
800
                                System.arraycopy(info.abyElem, 64, temp1, 0, 4);
801
                                psCell.rnghigh.y = DGN_INT32(temp1);
802
                                System.arraycopy(info.abyElem, 84, temp1, 0, 4);
803
                                psCell.origin.x = DGN_INT32(temp1);
804
                                System.arraycopy(info.abyElem, 88, temp1, 0, 4);
805
                                psCell.origin.y = DGN_INT32(temp1);
806

    
807
                                {
808
                                        double a;
809
                                        double b;
810
                                        double c;
811
                                        double d;
812
                                        double a2;
813
                                        double c2;
814
                                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
815
                                        a = DGN_INT32(temp1);
816
                                        System.arraycopy(info.abyElem, 72, temp1, 0, 4);
817
                                        b = DGN_INT32(temp1);
818
                                        System.arraycopy(info.abyElem, 76, temp1, 0, 4);
819
                                        c = DGN_INT32(temp1);
820
                                        System.arraycopy(info.abyElem, 80, temp1, 0, 4);
821
                                        d = DGN_INT32(temp1);
822
                                        a2 = a * a;
823
                                        c2 = c * c;
824
                                        psCell.xscale = Math.sqrt(a2 + c2) / 214748;
825
                                        psCell.yscale = Math.sqrt((b * b) + (d * d)) / 214748;
826
                                        psCell.rotation = Math.acos(a / Math.sqrt(a2 + c2));
827

    
828
                                        if (b <= 0) {
829
                                                psCell.rotation = (psCell.rotation * 180) / Math.PI;
830
                                        } else {
831
                                                psCell.rotation = 360 - ((psCell.rotation * 180) / Math.PI);
832
                                        }
833
                                }
834
                        } else {
835
                                byte[] temp1 = new byte[4];
836
                                System.arraycopy(info.abyElem, 52, temp1, 0, 4);
837
                                psCell.rnglow.x = DGN_INT32(temp1);
838
                                System.arraycopy(info.abyElem, 56, temp1, 0, 4);
839
                                psCell.rnglow.y = DGN_INT32(temp1);
840
                                System.arraycopy(info.abyElem, 60, temp1, 0, 4);
841
                                psCell.rnglow.z = DGN_INT32(temp1);
842
                                System.arraycopy(info.abyElem, 64, temp1, 0, 4);
843
                                psCell.rnghigh.x = DGN_INT32(temp1);
844
                                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
845
                                psCell.rnghigh.y = DGN_INT32(temp1);
846
                                System.arraycopy(info.abyElem, 72, temp1, 0, 4);
847
                                psCell.rnghigh.z = DGN_INT32(temp1);
848

    
849
                                System.arraycopy(info.abyElem, 112, temp1, 0, 4);
850
                                psCell.origin.x = DGN_INT32(temp1);
851
                                System.arraycopy(info.abyElem, 116, temp1, 0, 4);
852
                                psCell.origin.y = DGN_INT32(temp1);
853
                                System.arraycopy(info.abyElem, 120, temp1, 0, 4);
854
                                psCell.origin.z = DGN_INT32(temp1);
855
                        }
856

    
857
                        DGNTransformPoint(info, psCell.rnglow);
858
                        DGNTransformPoint(info, psCell.rnghigh);
859
                        DGNTransformPoint(info, psCell.origin);
860
                        elemento = psCell;
861

    
862
                        // DGNDumpElement(info,elemento,"");
863
                }
864

    
865
                        break;
866

    
867
                case DGNFileHeader.DGNT_CELL_LIBRARY: {
868
                        System.err.println("DGNT_CELL_LIBRARY");
869

    
870
                        DGNElemCellLibrary psCell = new DGNElemCellLibrary();
871
                        int iWord;
872
                        psCell.stype = DGNFileHeader.DGNST_CELL_LIBRARY;
873
                        DGNParseCore(info, psCell);
874

    
875
                        byte[] temp = new byte[psCell.name.length];
876
                        System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
877
                        DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[32])
878
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[33]) * 256),
879
                                        temp);
880
                        System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length);
881
                        DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[34])
882
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[35]) * 256),
883
                                        temp);
884
                        psCell.properties = info.abyElem[38] + (info.abyElem[39] * 256);
885
                        psCell.dispsymb = ByteUtils.byteToUnsignedInt(info.abyElem[40])
886
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256);
887
                        psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
888
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
889
                        psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
890
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
891
                        psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
892
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
893
                        psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
894
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
895
                        psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
896
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
897
                        psCell.numwords = ByteUtils.byteToUnsignedInt(info.abyElem[36])
898
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
899

    
900
                        for (iWord = 0; iWord < 9; iWord++) {
901
                                int iOffset = 52 + (iWord * 2);
902
                                System.arraycopy(psCell.name, iWord * 3, temp, 0,
903
                                                psCell.description.length);
904
                                DGNRad50ToAscii(
905
                                                ByteUtils.byteToUnsignedInt(info.abyElem[iOffset])
906
                                                                + (ByteUtils
907
                                                                                .byteToUnsignedInt(info.abyElem[iOffset + 1]) * 256),
908
                                                temp);
909
                        }
910

    
911
                        elemento = psCell;
912
                }
913

    
914
                        break;
915

    
916
                case DGNFileHeader.DGNT_LINE: {
917
                        DGNElemMultiPoint psLine = new DGNElemMultiPoint();
918
                        psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
919
                        DGNParseCore(info, psLine);
920
                        psLine.num_vertices = 2;
921
                        psLine.vertices = new DGNPoint[psLine.num_vertices];
922

    
923
                        if (info.dimension == 2) {
924
                                byte[] temp1 = new byte[4];
925
                                System.arraycopy(info.abyElem, 36, temp1, 0, 4);
926
                                psLine.vertices[0] = new DGNPoint();
927
                                psLine.vertices[0].x = DGN_INT32(temp1);
928
                                System.arraycopy(info.abyElem, 40, temp1, 0, 4);
929
                                psLine.vertices[0].y = DGN_INT32(temp1);
930
                                System.arraycopy(info.abyElem, 44, temp1, 0, 4);
931
                                psLine.vertices[1] = new DGNPoint();
932
                                psLine.vertices[1].x = DGN_INT32(temp1);
933
                                System.arraycopy(info.abyElem, 48, temp1, 0, 4);
934
                                psLine.vertices[1].y = DGN_INT32(temp1);
935
                        } else {
936
                                byte[] temp1 = new byte[4];
937
                                System.arraycopy(info.abyElem, 36, temp1, 0, 4);
938
                                psLine.vertices[0] = new DGNPoint();
939
                                psLine.vertices[0].x = DGN_INT32(temp1);
940
                                System.arraycopy(info.abyElem, 40, temp1, 0, 4);
941
                                psLine.vertices[0].y = DGN_INT32(temp1);
942
                                System.arraycopy(info.abyElem, 44, temp1, 0, 4);
943
                                psLine.vertices[0].z = DGN_INT32(temp1);
944
                                System.arraycopy(info.abyElem, 48, temp1, 0, 4);
945
                                psLine.vertices[1] = new DGNPoint();
946
                                psLine.vertices[1].x = DGN_INT32(temp1);
947
                                System.arraycopy(info.abyElem, 52, temp1, 0, 4);
948
                                psLine.vertices[1].y = DGN_INT32(temp1);
949
                                System.arraycopy(info.abyElem, 56, temp1, 0, 4);
950
                                psLine.vertices[1].z = DGN_INT32(temp1);
951
                        }
952

    
953
                        DGNTransformPoint(info, psLine.vertices[0]);
954
                        DGNTransformPoint(info, psLine.vertices[1]);
955
                        elemento = psLine;
956
                }
957

    
958
                        break;
959

    
960
                case DGNFileHeader.DGNT_LINE_STRING:
961
                case DGNFileHeader.DGNT_SHAPE: // regular
962
                case DGNFileHeader.DGNT_CURVE: // mal
963
                case DGNFileHeader.DGNT_BSPLINE: // aceptable
964
                {
965
                        DGNElemMultiPoint psLine = new DGNElemMultiPoint();
966
                        int i;
967
                        int count;
968
                        int pntsize = info.dimension * 4;
969

    
970
                        count = ByteUtils.byteToUnsignedInt(info.abyElem[36])
971
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
972
                        psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
973
                        DGNParseCore(info, psLine);
974

    
975
                        if (info.nElemBytes < (38 + (count * pntsize))) {
976
                                System.err.println("Error en los vertices de multipunto");
977
                                count = (info.nElemBytes - 38) / pntsize;
978

    
979
                                return null;
980
                        }
981

    
982
                        psLine.num_vertices = count;
983
                        psLine.vertices = new DGNPoint[psLine.num_vertices];
984

    
985
                        for (i = 0; i < psLine.num_vertices; i++) {
986
                                byte[] temp1 = new byte[4];
987
                                System.arraycopy(info.abyElem, 38 + (i * pntsize), temp1, 0, 4);
988
                                psLine.vertices[i] = new DGNPoint();
989
                                psLine.vertices[i].x = DGN_INT32(temp1);
990
                                System.arraycopy(info.abyElem, 42 + (i * pntsize), temp1, 0, 4);
991
                                psLine.vertices[i].y = DGN_INT32(temp1);
992

    
993
                                if (info.dimension == 3) {
994
                                        System.arraycopy(info.abyElem, 46 + (i * pntsize), temp1,
995
                                                        0, 4);
996
                                        psLine.vertices[i].z = DGN_INT32(temp1);
997
                                }
998

    
999
                                DGNTransformPoint(info, psLine.vertices[i]);
1000
                        }
1001

    
1002
                        elemento = psLine;
1003
                }
1004

    
1005
                        break;
1006

    
1007
                case DGNFileHeader.DGNT_GROUP_DATA:
1008

    
1009
                        if (nLevel == DGNFileHeader.DGN_GDL_COLOR_TABLE) {
1010
                                elemento = DGNParseColorTable(info);
1011
                        } else {
1012
                                elemento.stype = DGNFileHeader.DGNST_CORE;
1013
                                DGNParseCore(info, elemento);
1014
                        }
1015

    
1016
                        // System.err.println("DGNT_GROUP_DATA (nType = 5)");
1017
                        // DGNDumpElement(info, elemento,"");
1018
                        break;
1019

    
1020
                case DGNFileHeader.DGNT_ELLIPSE: {
1021
                        DGNElemArc psEllipse = new DGNElemArc();
1022

    
1023
                        psEllipse.stype = DGNFileHeader.DGNST_ARC;
1024
                        DGNParseCore(info, psEllipse);
1025

    
1026
                        int[] fin = new int[1];
1027
                        fin[0] = 0;
1028

    
1029
                        byte[] temp1 = new byte[8];
1030
                        System.arraycopy(info.abyElem, 36, temp1, 0, 8);
1031

    
1032
                        fin[0] = 0;
1033
                        psEllipse.primary_axis = DGNParseIEEE(temp1);
1034

    
1035
                        psEllipse.primary_axis *= info.scale;
1036
                        System.arraycopy(info.abyElem, 44, temp1, 0, 8);
1037
                        fin[0] = 0;
1038

    
1039
                        psEllipse.secondary_axis = DGNParseIEEE(temp1);
1040
                        psEllipse.secondary_axis *= info.scale;
1041

    
1042
                        if (info.dimension == 2) {
1043
                                System.arraycopy(info.abyElem, 52, temp1, 0, 4);
1044
                                psEllipse.rotation = DGN_INT32(temp1);
1045
                                psEllipse.rotation = psEllipse.rotation / 360000.0;
1046
                                System.arraycopy(info.abyElem, 56, temp1, 0, 8);
1047
                                fin[0] = 0;
1048

    
1049
                                psEllipse.origin.x = DGNParseIEEE(temp1);
1050
                                System.arraycopy(info.abyElem, 64, temp1, 0, 8);
1051
                                fin[0] = 0;
1052

    
1053
                                psEllipse.origin.y = DGNParseIEEE(temp1);
1054
                        } else {
1055
                                // leave quaternion for later
1056
                                System.arraycopy(info.abyElem, 68, temp1, 0, 8);
1057
                                fin[0] = 0;
1058
                                psEllipse.origin.x = DGNParseIEEE(temp1);
1059

    
1060
                                System.arraycopy(info.abyElem, 76, temp1, 0, 8);
1061
                                fin[0] = 0;
1062
                                psEllipse.origin.y = DGNParseIEEE(temp1);
1063

    
1064
                                System.arraycopy(info.abyElem, 84, temp1, 0, 8);
1065
                                fin[0] = 0;
1066
                                psEllipse.origin.z = DGNParseIEEE(temp1);
1067

    
1068
                                System.arraycopy(info.abyElem, 52, temp1, 0, 4);
1069
                                psEllipse.quat[0] = DGN_INT32(temp1);
1070
                                System.arraycopy(info.abyElem, 56, temp1, 0, 4);
1071
                                psEllipse.quat[1] = DGN_INT32(temp1);
1072
                                System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1073
                                psEllipse.quat[2] = DGN_INT32(temp1);
1074
                                System.arraycopy(info.abyElem, 64, temp1, 0, 4);
1075
                                psEllipse.quat[3] = DGN_INT32(temp1);
1076
                        }
1077

    
1078
                        // System.err.println("Punto antes de transformar:" +
1079
                        // psEllipse.origin.x + " " + psEllipse.origin.y);
1080
                        DGNTransformPoint(info, (psEllipse.origin));
1081

    
1082
                        // System.err.println("Punto DESPUES de transformar:" +
1083
                        // psEllipse.origin.x + " " + psEllipse.origin.y);
1084
                        psEllipse.startang = 0.0;
1085
                        psEllipse.sweepang = 360.0;
1086
                        elemento = psEllipse;
1087

    
1088
                        // DGNDumpElement(info, elemento,"");
1089
                }
1090

    
1091
                        break;
1092

    
1093
                case DGNFileHeader.DGNT_ARC: {
1094
                        DGNElemArc psEllipse = new DGNElemArc();
1095
                        double nSweepVal;
1096

    
1097
                        psEllipse.stype = DGNFileHeader.DGNST_ARC;
1098
                        DGNParseCore(info, psEllipse);
1099

    
1100
                        int[] fin = new int[1];
1101
                        fin[0] = 0;
1102

    
1103
                        byte[] temp1 = new byte[8];
1104
                        System.arraycopy(info.abyElem, 36, temp1, 0, 4);
1105
                        psEllipse.startang = DGN_INT32(temp1);
1106
                        psEllipse.startang = psEllipse.startang / 360000.0;
1107

    
1108
                        /*
1109
                         * if ((info.abyElem[41] & (byte) 0x80) != FALSE) { info.abyElem[41]
1110
                         * &= (byte) 0x7f; System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1111
                         * nSweepVal = -1 * DGN_INT32(temp1); } else {
1112
                         * System.arraycopy(info.abyElem, 40, temp1, 0, 4); } nSweepVal =
1113
                         * DGN_INT32(temp1);
1114
                         */
1115
                        if ((info.abyElem[41] & (byte) 0x80) != FALSE) {
1116
                                info.abyElem[41] &= (byte) 0x7f;
1117
                                System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1118
                                nSweepVal = -1 * DGN_INT32(temp1);
1119
                        } else {
1120
                                System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1121
                                nSweepVal = DGN_INT32(temp1);
1122
                        }
1123

    
1124
                        if (nSweepVal == 0) {
1125
                                psEllipse.sweepang = 360.0;
1126
                        } else {
1127
                                psEllipse.sweepang = nSweepVal / 360000.0;
1128
                        }
1129

    
1130
                        System.arraycopy(info.abyElem, 44, temp1, 0, 8);
1131
                        fin[0] = 0;
1132
                        psEllipse.primary_axis = DGNParseIEEE(temp1);
1133

    
1134
                        psEllipse.primary_axis *= info.scale;
1135
                        System.arraycopy(info.abyElem, 52, temp1, 0, 8);
1136
                        fin[0] = 0;
1137
                        psEllipse.secondary_axis = DGNParseIEEE(temp1);
1138

    
1139
                        psEllipse.secondary_axis *= info.scale;
1140

    
1141
                        if (info.dimension == 2) {
1142
                                System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1143
                                psEllipse.rotation = DGN_INT32(temp1);
1144
                                psEllipse.rotation = psEllipse.rotation / 360000.0;
1145
                                System.arraycopy(info.abyElem, 64, temp1, 0, 8);
1146
                                fin[0] = 0;
1147
                                psEllipse.origin.x = DGNParseIEEE(temp1);
1148

    
1149
                                System.arraycopy(info.abyElem, 72, temp1, 0, 8);
1150
                                fin[0] = 0;
1151
                                psEllipse.origin.y = DGNParseIEEE(temp1);
1152
                        } else {
1153
                                // for now we don't try to handle quaternion
1154
                                psEllipse.rotation = 0;
1155
                                System.arraycopy(info.abyElem, 76, temp1, 0, 8);
1156
                                fin[0] = 0;
1157

    
1158
                                psEllipse.origin.x = DGNParseIEEE(temp1);
1159
                                System.arraycopy(info.abyElem, 84, temp1, 0, 8);
1160
                                fin[0] = 0;
1161

    
1162
                                psEllipse.origin.y = DGNParseIEEE(temp1);
1163
                                System.arraycopy(info.abyElem, 92, temp1, 0, 8);
1164
                                fin[0] = 0;
1165

    
1166
                                psEllipse.origin.z = DGNParseIEEE(temp1);
1167
                                System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1168
                                psEllipse.quat[0] = DGN_INT32(temp1);
1169
                                System.arraycopy(info.abyElem, 64, temp1, 0, 4);
1170
                                psEllipse.quat[1] = DGN_INT32(temp1);
1171
                                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1172
                                psEllipse.quat[2] = DGN_INT32(temp1);
1173
                                System.arraycopy(info.abyElem, 72, temp1, 0, 4);
1174
                                psEllipse.quat[3] = DGN_INT32(temp1);
1175
                        }
1176

    
1177
                        DGNTransformPoint(info, (psEllipse.origin));
1178
                        elemento = psEllipse;
1179
                }
1180

    
1181
                        break;
1182

    
1183
                case DGNFileHeader.DGNT_TEXT: {
1184
                        DGNElemText psText = new DGNElemText();
1185
                        int num_chars;
1186
                        int text_off;
1187

    
1188
                        if (info.dimension == 2) {
1189
                                num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[58]);
1190
                        } else {
1191
                                num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[74]);
1192
                        }
1193

    
1194
                        psText.stype = DGNFileHeader.DGNST_TEXT;
1195
                        DGNParseCore(info, psText);
1196

    
1197
                        psText.font_id = ByteUtils.byteToUnsignedInt(info.abyElem[36]);
1198
                        psText.justification = ByteUtils
1199
                                        .byteToUnsignedInt(info.abyElem[37]);
1200

    
1201
                        byte[] temp1 = new byte[8];
1202
                        System.arraycopy(info.abyElem, 38, temp1, 0, 4);
1203
                        psText.length_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
1204
                        System.arraycopy(info.abyElem, 42, temp1, 0, 4);
1205
                        psText.height_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
1206

    
1207
                        int[] fin = new int[1];
1208
                        fin[0] = 0;
1209

    
1210
                        if (info.dimension == 2) {
1211
                                System.arraycopy(info.abyElem, 46, temp1, 0, 4);
1212
                                psText.rotation = DGN_INT32(temp1);
1213
                                psText.rotation = psText.rotation / 360000.0;
1214
                                System.arraycopy(info.abyElem, 50, temp1, 0, 4);
1215
                                psText.origin.x = DGN_INT32(temp1);
1216
                                System.arraycopy(info.abyElem, 54, temp1, 0, 4);
1217
                                psText.origin.y = DGN_INT32(temp1);
1218
                                text_off = 60;
1219
                        } else {
1220
                                /* leave quaternion for later */
1221
                                System.arraycopy(info.abyElem, 62, temp1, 0, 4);
1222
                                psText.origin.x = DGN_INT32(temp1);
1223
                                System.arraycopy(info.abyElem, 66, temp1, 0, 4);
1224
                                psText.origin.y = DGN_INT32(temp1);
1225
                                System.arraycopy(info.abyElem, 70, temp1, 0, 4);
1226
                                psText.origin.z = DGN_INT32(temp1);
1227
                                text_off = 76;
1228
                        }
1229

    
1230
                        // System.err.println("Punto antes de transformar:" +
1231
                        // psText.origin.x + " " + psText.origin.y);
1232
                        DGNTransformPoint(info, (psText.origin));
1233

    
1234
                        // AQUI FALTA METER ALGO PARA SOPORTAR TEXTOS MULTYBYTE
1235
                        byte[] temp = new byte[num_chars];
1236
                        System.arraycopy(info.abyElem, text_off, temp, 0, num_chars);
1237

    
1238
                        // fin[0] = 0;
1239
                        String strAux = null;
1240

    
1241
                        try {
1242
                                psText.string = new String(temp, "ISO-8859-1");
1243

    
1244
                                // System.err.println(strAux);
1245
                        } catch (Exception e) {
1246
                                e.printStackTrace();
1247
                        }
1248

    
1249
                        elemento = psText;
1250
                }
1251

    
1252
                        break;
1253

    
1254
                case DGNFileHeader.DGNT_TCB:
1255
                        if (info.got_tcb == FALSE) {
1256
                                elemento = DGNParseTCB(info);
1257
                                elemento.level = nLevel;
1258
                                elemento.type = nType;
1259
                        }
1260
                        break;
1261

    
1262
                case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
1263
                case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER: {
1264
                        DGNElemComplexHeader psHdr = new DGNElemComplexHeader();
1265

    
1266
                        psHdr.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
1267
                        DGNParseCore(info, psHdr);
1268

    
1269
                        psHdr.totlength = ByteUtils.byteToUnsignedInt(info.abyElem[36])
1270
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
1271
                        psHdr.numelems = ByteUtils.byteToUnsignedInt(info.abyElem[38])
1272
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256);
1273
                        elemento = psHdr;
1274
                }
1275

    
1276
                        break;
1277

    
1278
                case DGNFileHeader.DGNT_TAG_VALUE: {
1279
                        DGNElemTagValue psTag = new DGNElemTagValue();
1280

    
1281
                        psTag.stype = DGNFileHeader.DGNST_TAG_VALUE;
1282
                        DGNParseCore(info, psTag);
1283

    
1284
                        int[] fin = new int[1];
1285
                        fin[0] = 0;
1286

    
1287
                        byte[] temp1 = new byte[8];
1288
                        psTag.tagType = ByteUtils.byteToUnsignedInt(info.abyElem[74])
1289
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[75]) * 256);
1290
                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1291
                        fin[0] = 0;
1292
                        psTag.tagSet = ByteUtils.bytesToInt(temp1, fin);
1293

    
1294
                        psTag.tagSet = CPL_LSBWORD32(psTag.tagSet);
1295
                        psTag.tagIndex = ByteUtils.byteToUnsignedInt(info.abyElem[72])
1296
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[73]) * 256);
1297
                        psTag.tagLength = ByteUtils.byteToUnsignedInt(info.abyElem[150])
1298
                                        + (ByteUtils.byteToUnsignedInt(info.abyElem[151]) * 256);
1299

    
1300
                        if (psTag.tagType == 1) {
1301
                                byte[] temp = new byte[info.abyElem.length - 154];
1302
                                System.arraycopy(info.abyElem, 4, temp1, 0, // 154
1303
                                                4); // info.abyElem.length - 154
1304
                                fin[0] = 0;
1305
                                psTag.tagValue.string = CPLStrdup(ByteUtils.bytesToString(
1306
                                                temp1, fin).toCharArray());
1307
                        } else if (psTag.tagType == 3) {
1308
                                byte[] temp = new byte[4];
1309
                                System.arraycopy(info.abyElem, 154, temp1, 0, 4);
1310
                                fin[0] = 0;
1311
                                psTag.tagValue.integer = ByteUtils.bytesToInt(temp1, fin);
1312

    
1313
                                psTag.tagValue.integer = CPL_LSBWORD32((int) psTag.tagValue.integer);
1314
                        } else if (psTag.tagType == 4) {
1315
                                byte[] temp = new byte[8];
1316
                                System.arraycopy(info.abyElem, 154, temp1, 0, 8);
1317
                                fin[0] = 0;
1318
                                psTag.tagValue.real = DGNParseIEEE(temp1);
1319
                        }
1320

    
1321
                        elemento = psTag;
1322
                }
1323

    
1324
                        break;
1325

    
1326
                /*
1327
                 * case DGNFileHeader.DGNT_APPLICATION_ELEM: if (nLevel == 24) {
1328
                 * elemento = DGNParseTagSet(info); } else { elemento.stype =
1329
                 * DGNFileHeader.DGNST_CORE; DGNParseCore(info, elemento); } break;
1330
                 */
1331
                default: {
1332
                        // System.err.println("Entra un " + nType +
1333
                        // " en DGNProcessElement");
1334
                        elemento.stype = DGNFileHeader.DGNST_CORE;
1335
                        DGNParseCore(info, elemento);
1336
                }
1337

    
1338
                        break;
1339
                }
1340

    
1341
                /* -------------------------------------------------------------------- */
1342
                /* If the element structure type is "core" or if we are running */
1343
                /* in "capture all" mode, record the complete binary image of */
1344
                /* the element. */
1345
                /* -------------------------------------------------------------------- */
1346
                if ((elemento.stype == DGNFileHeader.DGNST_CORE)
1347
                                || ((info.options & DGNFileHeader.DGNO_CAPTURE_RAW_DATA) != FALSE)) {
1348
                        elemento.raw_bytes = info.nElemBytes;
1349

    
1350
                        elemento.raw_data = new byte[elemento.raw_bytes];
1351

    
1352
                        int[] fin = new int[1];
1353
                        fin[0] = 0;
1354
                        System.arraycopy(info.abyElem, 0, elemento.raw_data, 0,
1355
                                        elemento.raw_bytes);
1356
                }
1357

    
1358
                /* -------------------------------------------------------------------- */
1359
                /* Collect some additional generic information. */
1360
                /* -------------------------------------------------------------------- */
1361
                elemento.element_id = info.next_element_id - 1;
1362

    
1363
                elemento.offset = info.ftall - info.nElemBytes;
1364
                elemento.size = info.nElemBytes;
1365

    
1366
                // DGNDumpElement(info, elemento,"");
1367
                return elemento;
1368
        }
1369

    
1370
        /**
1371
         * DOCUMENT ME!
1372
         * 
1373
         * @param d
1374
         *            DOCUMENT ME!
1375
         * 
1376
         * @return DOCUMENT ME!
1377
         */
1378
        private double DGNParseIEEE(double d) {
1379
                byte[] temp = new byte[8];
1380
                int[] f = { 0 };
1381
                ByteUtils.doubleToBytes(d, temp, f);
1382

    
1383
                return DGNParseIEEE(temp);
1384
        }
1385

    
1386
        /**
1387
         * DOCUMENT ME!
1388
         * 
1389
         * @param b
1390
         *            DOCUMENT ME!
1391
         * 
1392
         * @return DOCUMENT ME!
1393
         */
1394
        private double DGNParseIEEE(byte[] b) {
1395
                byte BYTE2 = b[7];
1396
                byte BYTE3 = b[6];
1397
                byte BYTE0 = b[5];
1398
                byte BYTE1 = b[4];
1399
                byte BYTE6 = b[3];
1400
                byte BYTE7 = b[2];
1401
                byte BYTE4 = b[1];
1402
                byte BYTE5 = b[0];
1403
                int sign;
1404
                int exponent;
1405
                int fraction;
1406
                double value;
1407
                int hi;
1408
                int lo;
1409
                int rndbits;
1410

    
1411
                /* -------------------------------------------------------------------- */
1412
                /* Save the sign of the double */
1413
                /* -------------------------------------------------------------------- */
1414
                byte[] temp = new byte[4];
1415
                byte[] temp1 = new byte[4];
1416

    
1417
                temp[3] = BYTE7;
1418
                temp[2] = BYTE6;
1419
                temp[1] = BYTE5;
1420
                temp[0] = BYTE4;
1421

    
1422
                int[] f = { 0 };
1423
                hi = ByteUtils.bytesToInt(temp, f);
1424
                sign = hi & 0x80000000;
1425

    
1426
                /* -------------------------------------------------------------------- */
1427
                /* Adjust the exponent so that we may work with it */
1428
                /* -------------------------------------------------------------------- */
1429
                exponent = hi >> 23;
1430
                exponent = exponent & 0x000000ff;
1431

    
1432
                if (exponent != 0) {
1433
                        exponent = exponent - 129 + 1023;
1434
                }
1435

    
1436
                /* -------------------------------------------------------------------- */
1437
                /* Save the bits that we are discarding so we can round properly */
1438
                /* -------------------------------------------------------------------- */
1439
                temp[3] = BYTE3;
1440
                temp[2] = BYTE2;
1441
                temp[1] = BYTE1;
1442
                temp[0] = BYTE0;
1443

    
1444
                f[0] = 0;
1445
                lo = ByteUtils.bytesToInt(temp, f);
1446
                rndbits = lo & 0x00000007;
1447

    
1448
                lo = lo >> 3;
1449
                lo = (lo & 0x1fffffff) | (hi << 29);
1450

    
1451
                if (rndbits != 0) {
1452
                        lo = lo | 0x00000001;
1453
                }
1454

    
1455
                /* -------------------------------------------------------------------- */
1456
                /* Shift the hi-order int over 3 and insert the exponent and sign */
1457
                /* -------------------------------------------------------------------- */
1458
                hi = hi >> 3;
1459
                hi = hi & 0x000fffff;
1460
                hi = hi | (exponent << 20) | sign;
1461
                f[0] = 0;
1462
                ByteUtils.intToBytes(hi, temp, f);
1463
                f[0] = 0;
1464
                ByteUtils.intToBytes(lo, temp1, f);
1465

    
1466
                byte[] result = new byte[8];
1467
                result[7] = temp1[3];
1468
                result[6] = temp1[2];
1469
                result[5] = temp1[1];
1470
                result[4] = temp1[0];
1471
                result[3] = temp[3];
1472
                result[2] = temp[2];
1473
                result[1] = temp[1];
1474
                result[0] = temp[0];
1475

    
1476
                f[0] = 0;
1477

    
1478
                value = ByteUtils.bytesToDouble(result, f);
1479

    
1480
                return value;
1481
        }
1482

    
1483
        /************************************************************************/
1484
        /* DGN2IEEEDouble() */
1485
        /************************************************************************/
1486
        /**
1487
         * Cambia el double a IEEDouble.
1488
         * 
1489
         * @param dbl
1490
         *            double de entrada.
1491
         */
1492
        private double DGN2IEEEDouble(double dbl) {
1493
                int tempInt = (int) Double.doubleToLongBits(dbl);
1494
                int low = (tempInt & 0xffff0000) >>> 16; // >>>: Right shift without
1495
                // sign extension
1496
                int high = (tempInt & 0x0000ffff) << 16;
1497
                tempInt = high | low;
1498
                int s = ((tempInt >> 31) == 0) ? 1 : -1;
1499
                int e = ((tempInt >> 23) & 0xff);
1500
                int m = (tempInt & 0x7fffff) | 0x800000;
1501
                return ((s * m * 2 * Math.pow(2, e - 128 - 25)));
1502
        }
1503

    
1504
        /**
1505
         * DOCUMENT ME!
1506
         * 
1507
         * @param dbl
1508
         *            DOCUMENT ME!
1509
         */
1510
        private double IEEE2DGNDouble(double dbl) {
1511
                double64 dt = new double64();
1512

    
1513
                dt.hi = 0;
1514
                dt.lo = 0;
1515

    
1516
                long sign;
1517
                long exponent;
1518
                long rndbits;
1519
                byte[] srclo = new byte[4];
1520
                byte[] srchi = new byte[4];
1521
                byte[] destlo = new byte[4];
1522
                byte[] desthi = new byte[4];
1523
                byte[] src = new byte[8];
1524
                byte[] dest = new byte[8];
1525

    
1526
                for (int i = 0; i < 8; i++) {
1527
                        src[i] = '0';
1528
                        dest[i] = '0';
1529
                }
1530

    
1531
                int[] fin = new int[1];
1532

    
1533
                if (LSB == TRUE) {
1534
                        fin[0] = 0;
1535
                        ByteUtils.doubleToBytes(dbl, src, fin);
1536
                        dest[0] = src[4];
1537
                        dest[1] = src[5];
1538
                        dest[2] = src[6];
1539
                        dest[3] = src[7];
1540
                        dest[4] = src[0];
1541
                        dest[5] = src[1];
1542
                        dest[6] = src[2];
1543
                        dest[7] = src[3];
1544
                } else {
1545
                        // memcpy( &dt, dbl, 8 );
1546
                }
1547

    
1548
                sign = dt.hi & 0x80000000;
1549
                exponent = dt.hi >> 20;
1550
                exponent = exponent & 0x000007ff;
1551

    
1552
                /* -------------------------------------------------------------------- */
1553
                /* An exponent of zero means a zero value. */
1554
                /* -------------------------------------------------------------------- */
1555
                if (exponent != FALSE) {
1556
                        exponent = exponent - 1023 + 129;
1557
                }
1558

    
1559
                /* -------------------------------------------------------------------- */
1560
                /* In the case of overflow, return the largest number we can */
1561
                /* -------------------------------------------------------------------- */
1562
                if (exponent > 255) {
1563
                        fin[0] = 0;
1564
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1565

    
1566
                        if (sign != FALSE) {
1567
                                dest[1] = 0xf;
1568
                        } else {
1569
                                dest[1] = 0x7f;
1570
                        }
1571

    
1572
                        dest[0] = 0xf;
1573
                        dest[2] = 0xf;
1574
                        dest[3] = 0xf;
1575
                        dest[4] = 0xf;
1576
                        dest[5] = 0xf;
1577
                        dest[6] = 0xf;
1578
                        dest[7] = 0xf;
1579

    
1580
                        return ByteUtils.bytesToDouble(dest, new int[0]);
1581
                }
1582
                /* -------------------------------------------------------------------- */
1583
                /* In the case of of underflow return zero */
1584
                /* -------------------------------------------------------------------- */
1585
                else if ((exponent < 0) || ((exponent == 0) && (sign == 0))) {
1586
                        fin[0] = 0;
1587
                        ByteUtils.doubleToBytes(dbl, dest, fin);
1588
                        dest[0] = 0x00;
1589
                        dest[1] = 0x00;
1590
                        dest[2] = 0x00;
1591
                        dest[3] = 0x00;
1592
                        dest[4] = 0x00;
1593
                        dest[5] = 0x00;
1594
                        dest[6] = 0x00;
1595
                        dest[7] = 0x00;
1596

    
1597
                        return 0.0;
1598
                } else {
1599
                        /*
1600
                         * ------------------------------------------------------------------
1601
                         * --
1602
                         */
1603
                        /* Shift the fraction 3 bits left and set the exponent and sign */
1604
                        /*
1605
                         * ------------------------------------------------------------------
1606
                         * --
1607
                         */
1608
                        System.arraycopy(dest, 0, destlo, 0, 4);
1609
                        fin[0] = 0;
1610
                        dt.lo = ByteUtils.bytesToLong(destlo, fin);
1611
                        System.arraycopy(dest, 4, desthi, 0, 4);
1612
                        fin[0] = 0;
1613
                        dt.hi = ByteUtils.bytesToLong(desthi, fin);
1614

    
1615
                        dt.hi = dt.hi << 3;
1616
                        dt.hi = dt.hi | (dt.lo >> 29);
1617
                        dt.hi = dt.hi & 0x007fffff;
1618
                        dt.hi = dt.hi | (exponent << 23) | sign;
1619

    
1620
                        dt.lo = dt.lo << 3;
1621
                }
1622

    
1623
                /* -------------------------------------------------------------------- */
1624
                /* Convert the double back to VAX format */
1625
                /* -------------------------------------------------------------------- */
1626
                fin[0] = 0;
1627

    
1628
                ByteUtils.longToBytes(dt.lo, srclo, fin);
1629

    
1630
                fin[0] = 0;
1631
                ByteUtils.longToBytes(dt.hi, srchi, fin);
1632

    
1633
                if (LSB == TRUE) {
1634
                        dest[2] = srclo[0];
1635
                        dest[3] = srclo[1];
1636
                        dest[0] = srclo[2];
1637
                        dest[1] = srclo[3];
1638
                        dest[6] = srchi[0];
1639
                        dest[7] = srchi[1];
1640
                        dest[4] = srchi[2];
1641
                        dest[5] = srchi[3];
1642
                } else {
1643
                        dest[1] = srclo[0];
1644
                        dest[0] = srclo[1];
1645
                        dest[3] = srclo[2];
1646
                        dest[2] = srclo[3];
1647
                        dest[5] = srchi[0];
1648
                        dest[4] = srchi[1];
1649
                        dest[7] = srchi[2];
1650
                        dest[6] = srchi[3];
1651
                }
1652

    
1653
                fin[0] = 0;
1654
                dbl = ByteUtils.bytesToDouble(dest, fin);
1655
                return dbl;
1656

    
1657
                // //System.out.println("dbl=  " + dbl);
1658
        }
1659

    
1660
        /************************************************************************/
1661
        /* DGNElemTypeHasDispHdr() */
1662
        /************************************************************************/
1663

    
1664
        /**
1665
         * Does element type have display header.
1666
         * 
1667
         * @param nElemType
1668
         *            element type (0-63) to test.
1669
         * 
1670
         * @return TRUE if elements of passed in type have a display header after
1671
         *         the core element header, or FALSE otherwise.
1672
         */
1673
        private int DGNElemTypeHasDispHdr(int nElemType) {
1674
                switch (nElemType) {
1675
                case 0:
1676
                case DGNFileHeader.DGNT_TCB:
1677
                case DGNFileHeader.DGNT_CELL_LIBRARY:
1678
                case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
1679
                case 32:
1680
                case 44:
1681
                case 48:
1682
                case 49:
1683
                case 50:
1684
                case 51:
1685
                case 57:
1686
                case 63:
1687
                        return FALSE;
1688

    
1689
                default:
1690
                        return TRUE;
1691
                }
1692
        }
1693

    
1694
        /**
1695
         * DOCUMENT ME!
1696
         * 
1697
         * @param info
1698
         *            DOCUMENT ME!
1699
         * @param elemento
1700
         *            DOCUMENT ME!
1701
         * 
1702
         * @return DOCUMENT ME!
1703
         */
1704
        private int DGNParseCore(DGNInfo info, DGNElemCore elemento) {
1705
                byte[] psData = info.abyElem; // 0
1706

    
1707
                elemento.level = psData[0] & (byte) 0x3f;
1708
                elemento.complex = psData[0] & (byte) 0x80;
1709
                elemento.deleted = psData[1] & (byte) 0x80;
1710
                elemento.type = psData[1] & (byte) 0x7f;
1711

    
1712
                if ((info.nElemBytes >= 36)
1713
                                && (DGNElemTypeHasDispHdr(elemento.type) == TRUE)) {
1714
                        // (elemento.type != DGNFileHeader.DGNT_CELL_LIBRARY)) {
1715
                        elemento.graphic_group = psData[28] + (psData[29] * 256);
1716
                        elemento.properties = psData[32] + (psData[33] * 256);
1717

    
1718
                        elemento.style = psData[34] & (byte) 0x7;
1719
                        elemento.weight = (psData[34] & (byte) 0xf8) >> 3;
1720

    
1721
                        byte aux = psData[35];
1722

    
1723
                        // System.out.println("aux = " + aux);
1724
                        elemento.color = ByteUtils.getUnsigned(aux);
1725

    
1726
                        // elemento.color = psData[35];
1727
                        // System.out.println("elemento.color = " + elemento.color);
1728
                } else {
1729
                        elemento.graphic_group = 0;
1730
                        elemento.properties = 0;
1731
                        elemento.style = 0;
1732
                        elemento.weight = 0;
1733
                        elemento.color = 0;
1734
                }
1735

    
1736
                if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
1737
                        // if ((elemento.properties & DGNFileHeader.DGNPF_ATTRIBUTES) ==
1738
                        // TRUE) {
1739
                        int nAttIndex;
1740

    
1741
                        nAttIndex = ByteUtils.getUnsigned(psData[30])
1742
                                        + (ByteUtils.getUnsigned(psData[31]) * 256);
1743

    
1744
                        int numBytes = info.nElemBytes - (nAttIndex * 2) - 32;
1745

    
1746
                        if ((numBytes > 0)) {
1747
                                // Como m?ximo guardamos 10 bytes (Total, lo queremos para el
1748
                                // color....
1749
                                // if (numBytes > 10) numBytes = 10;
1750
                                elemento.attr_bytes = numBytes;
1751

    
1752
                                elemento.attr_data = new byte[elemento.attr_bytes];
1753

    
1754
                                // System.out.println("nAttIndex = " + nAttIndex +
1755
                                // " numBytes = " + numBytes );
1756
                                System.arraycopy(psData, (nAttIndex * 2) + 32,
1757
                                                elemento.attr_data, 0, elemento.attr_bytes);
1758
                        }
1759
                }
1760

    
1761
                return TRUE;
1762
        }
1763

    
1764
        /**
1765
         * DOCUMENT ME!
1766
         * 
1767
         * @param rad50
1768
         *            DOCUMENT ME!
1769
         * @param str
1770
         *            DOCUMENT ME!
1771
         */
1772
        private void DGNRad50ToAscii(int rad50, byte[] str) {
1773
                byte cTimes;
1774
                int value;
1775
                int temp;
1776
                byte ch = '\0';
1777
                int i = 0;
1778

    
1779
                while (rad50 > 0) {
1780
                        value = rad50;
1781
                        cTimes = 0;
1782

    
1783
                        while (value >= 40) {
1784
                                value /= 40;
1785
                                cTimes++;
1786
                        }
1787

    
1788
                        byte[] abc = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
1789
                                        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
1790
                                        'W', 'X', 'Y', 'Z' };
1791
                        byte[] num = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
1792

    
1793
                        /* Map 0..39 to ASCII */
1794
                        if (value == 0) {
1795
                                ch = ' '; /* space */
1796
                        } else if ((value >= 1) && (value <= 26)) {
1797
                                ch = abc[value - 1]; /* printable alpha A..Z */
1798
                        } else if (value == 27) {
1799
                                ch = '$'; /* dollar */
1800
                        } else if (value == 28) {
1801
                                ch = '.'; /* period */
1802
                        } else if (value == 29) {
1803
                                ch = ' '; /* unused char, emit a space instead */
1804
                        } else if ((value >= 30) && (value <= 39)) {
1805
                                ch = num[value - 30]; /* digit 0..9 */
1806
                        }
1807

    
1808
                        str[i] = ch;
1809
                        i++;
1810

    
1811
                        temp = 1;
1812

    
1813
                        while (cTimes-- > 0) {
1814
                                temp *= 40;
1815
                        }
1816

    
1817
                        rad50 -= (value * temp);
1818
                }
1819

    
1820
                /* Do zero-terminate */
1821
                str[i] = '\0';
1822
        }
1823

    
1824
        /**
1825
         * Transforma el punto.
1826
         * 
1827
         * @param info
1828
         *            Informaci?n del DGN.
1829
         * @param psPoint
1830
         *            Punto.
1831
         */
1832
        private void DGNTransformPoint(DGNInfo info, DGNPoint psPoint) {
1833
                psPoint.x = (psPoint.x * info.scale) - info.origin_x;
1834

    
1835
                // System.out.println("info.scale= "+info.scale+"info.origin_x= "+info.origin_x);
1836
                psPoint.y = (psPoint.y * info.scale) - info.origin_y;
1837

    
1838
                // System.out.println("info.origin_y= "+info.origin_y);
1839
                psPoint.z = (psPoint.z * info.scale) - info.origin_z;
1840

    
1841
                // System.out.println("x= "+psPoint.x+"y= "+psPoint.y);
1842
        }
1843

    
1844
        /**
1845
         * DOCUMENT ME!
1846
         * 
1847
         * @param psDGN
1848
         *            DOCUMENT ME!
1849
         * 
1850
         * @return DOCUMENT ME!
1851
         */
1852
        private DGNElemCore DGNParseColorTable(DGNInfo psDGN) {
1853
                DGNElemColorTable psColorTable = new DGNElemColorTable();
1854

    
1855
                psColorTable.stype = DGNFileHeader.DGNST_COLORTABLE;
1856

    
1857
                DGNParseCore(psDGN, psColorTable);
1858

    
1859
                psColorTable.screen_flag = ByteUtils
1860
                                .byteToUnsignedInt(psDGN.abyElem[36])
1861
                                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[37]) * 256);
1862

    
1863
                int[] fin = new int[1];
1864
                fin[0] = 0;
1865

    
1866
                byte[] temp = new byte[3];
1867
                System.arraycopy(psDGN.abyElem, 38, temp, 0, 3);
1868
                psColorTable.color_info[255] = temp;
1869

    
1870
                byte[] temp2 = new byte[765];
1871
                System.arraycopy(psDGN.abyElem, 41, temp2, 0, 765);
1872

    
1873
                int k = 0;
1874

    
1875
                for (int i = 0; i < 255; i++) {
1876
                        for (int j = 0; j < 3; j++) {
1877
                                psColorTable.color_info[i][j] = temp2[k];
1878
                                k++;
1879
                        }
1880

    
1881
                        // System.err.println("Color " + psColorTable.color_info[i][0] + " "
1882
                        // +
1883
                        // psColorTable.color_info[i][1] + " " +
1884
                        // psColorTable.color_info[i][2]);
1885
                }
1886

    
1887
                if (psDGN.got_color_table == FALSE) {
1888
                        psDGN.color_table = psColorTable.color_info;
1889

    
1890
                        psDGN.got_color_table = 1;
1891
                }
1892

    
1893
                return psColorTable;
1894
        }
1895

    
1896
        /**
1897
         * DOCUMENT ME!
1898
         * 
1899
         * @param psDGN
1900
         *            DOCUMENT ME!
1901
         * 
1902
         * @return DOCUMENT ME!
1903
         */
1904
        private DGNElemCore DGNParseTCB(DGNInfo psDGN) {
1905
                DGNElemTCB psTCB = new DGNElemTCB();
1906
                int iView;
1907
                int[] fin = new int[1];
1908
                psTCB.stype = DGNFileHeader.DGNST_TCB;
1909
                DGNParseCore(psDGN, psTCB);
1910

    
1911
                if ((psDGN.abyElem[1214] & (byte) 0x40) != FALSE) {
1912
                        psTCB.dimension = 3;
1913
                } else {
1914
                        psTCB.dimension = 2;
1915
                }
1916

    
1917
                // psTCB.dimension = 3;
1918
                fin[0] = 0;
1919

    
1920
                byte[] temp1 = new byte[8];
1921
                System.arraycopy(psDGN.abyElem, 1112, temp1, 0, 4);
1922
                psTCB.subunits_per_master = DGN_INT32(temp1);
1923

    
1924
                psTCB.master_units[0] = (char) (psDGN.abyElem[1120]);
1925
                psTCB.master_units[1] = (char) (psDGN.abyElem[1121]);
1926
                psTCB.master_units[2] = '\0';
1927

    
1928
                System.arraycopy(psDGN.abyElem, 1116, temp1, 0, 4);
1929
                psTCB.uor_per_subunit = DGN_INT32(temp1);
1930

    
1931
                psTCB.sub_units[0] = (char) (psDGN.abyElem[1122]);
1932
                psTCB.sub_units[1] = (char) (psDGN.abyElem[1123]);
1933
                psTCB.sub_units[2] = '\0';
1934

    
1935
                /* Get global origin */
1936
                System.arraycopy(psDGN.abyElem, 1240, temp1, 0, 8);
1937
                ByteBuffer buffer = ByteBuffer.wrap(psDGN.abyElem);
1938
                buffer.order(ByteOrder.LITTLE_ENDIAN);
1939
                psTCB.origin_x = buffer.getDouble(1240);
1940
                psTCB.origin_y = buffer.getDouble(1248);
1941
                psTCB.origin_z = buffer.getDouble(1256);
1942

    
1943
                /* Transform to IEEE */
1944
                psTCB.origin_x = DGN2IEEEDouble(psTCB.origin_x);
1945
                psTCB.origin_y = DGN2IEEEDouble(psTCB.origin_y);
1946
                psTCB.origin_z = DGN2IEEEDouble(psTCB.origin_z);
1947

    
1948
                /* Convert from UORs to master units. */
1949
                if ((psTCB.uor_per_subunit != 0) && (psTCB.subunits_per_master != 0)) {
1950
                        psTCB.origin_x = psTCB.origin_x
1951
                                        / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
1952
                        psTCB.origin_y = psTCB.origin_y
1953
                                        / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
1954
                        psTCB.origin_z = psTCB.origin_z
1955
                                        / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
1956
                }
1957

    
1958
                // psDGN.dimension = psTCB.dimension;
1959
                if (psDGN.got_tcb == FALSE) {
1960
                        psDGN.got_tcb = TRUE;
1961

    
1962
                        psDGN.origin_x = psTCB.origin_x;
1963
                        psDGN.origin_y = psTCB.origin_y;
1964
                        psDGN.origin_z = psTCB.origin_z;
1965
                        if ((psTCB.uor_per_subunit != 0)
1966
                                        && (psTCB.subunits_per_master != 0)) {
1967
                                psDGN.scale = 1.0 / (psTCB.uor_per_subunit * psTCB.subunits_per_master);
1968
                        }
1969
                }
1970

    
1971
                System.err.println("Ojo: HAY TCB!!");
1972
                System.out.println("Datos del TCB: " + psTCB.origin_x + " "
1973
                                + psTCB.origin_y);
1974
                System.out.println("psTCB.uor_per_subunit: " + psTCB.uor_per_subunit
1975
                                + " psTCB.subunits_per_master: " + psTCB.subunits_per_master);
1976
                // System.out.println("psTCB.master_units = " + new
1977
                // String(psTCB.master_units) +
1978
                // " psTCB.sub_units = " + new String(psTCB.sub_units));
1979
                System.out.println("psTCB.origen = " + psTCB.origin_x + " "
1980
                                + psTCB.origin_y);
1981
                System.out.println("psDGN.scale = " + psDGN.scale);
1982
                System.out.println("psDGN.origen = " + psDGN.origin_x + " "
1983
                                + psDGN.origin_y);
1984
                System.out.println("psDGN.dimension = " + psDGN.dimension);
1985
                /* Collect views */
1986
                for (iView = 0; iView < 8; iView++) {
1987
                        byte[] pabyRawView = new byte[psDGN.abyElem.length];
1988
                        fin[0] = 0;
1989
                        System.arraycopy(psDGN.abyElem, (46 + (iView * 118)), pabyRawView,
1990
                                        0, psDGN.abyElem.length - (46 + (iView * 118)));
1991

    
1992
                        psTCB.views[iView] = new DGNViewInfo();
1993
                        psTCB.views[iView].flags = ByteUtils
1994
                                        .byteToUnsignedInt(pabyRawView[0])
1995
                                        + (ByteUtils.byteToUnsignedInt(pabyRawView[1]) * 256);
1996

    
1997
                        byte[] temp2 = new byte[4];
1998
                        int f = 0;
1999

    
2000
                        for (int j = 0; j < 8; j++) {
2001
                                System.arraycopy(pabyRawView, j + 2, temp2, 0, 1);
2002
                                fin[0] = 0;
2003
                                psTCB.views[iView].levels[f] = temp2[0];
2004
                                f++;
2005
                        }
2006

    
2007
                        psTCB.views[iView].origin = new DGNPoint();
2008
                        System.arraycopy(pabyRawView, 10, temp1, 0, 4);
2009
                        psTCB.views[iView].origin.x = DGN_INT32(temp1);
2010

    
2011
                        System.arraycopy(pabyRawView, 14, temp1, 0, 4);
2012
                        psTCB.views[iView].origin.y = DGN_INT32(temp1);
2013
                        System.arraycopy(pabyRawView, 18, temp1, 0, 4);
2014
                        psTCB.views[iView].origin.z = DGN_INT32(temp1);
2015
                        DGNTransformPoint(psDGN, (psTCB.views[iView].origin));
2016

    
2017
                        psTCB.views[iView].delta = new DGNPoint();
2018
                        System.arraycopy(pabyRawView, 22, temp1, 0, 4);
2019
                        psTCB.views[iView].delta.x = DGN_INT32(temp1);
2020
                        System.arraycopy(pabyRawView, 26, temp1, 0, 4);
2021
                        psTCB.views[iView].delta.y = DGN_INT32(temp1);
2022
                        System.arraycopy(pabyRawView, 30, temp1, 0, 4);
2023
                        psTCB.views[iView].delta.z = DGN_INT32(temp1);
2024

    
2025
                        psTCB.views[iView].delta.x *= psDGN.scale;
2026
                        psTCB.views[iView].delta.y *= psDGN.scale;
2027
                        psTCB.views[iView].delta.z *= psDGN.scale;
2028

    
2029
                        // memcpy( psTCB.views[iView].transmatrx, pabyRawView + 34,
2030
                        // sizeof(double) * 9 );
2031
                        psTCB.views[iView].transmatrx = new double[9];
2032

    
2033
                        for (int k = 0; k < 9; k++) {
2034
                                System.arraycopy(pabyRawView, (34 + (8 * k)), temp1, 0, 8);
2035

    
2036
                                // fin[0]=0;
2037
                                // double d=ByteUtils.bytesToDouble(temp1,fin);
2038
                                fin[0] = 0;
2039
                                psTCB.views[iView].transmatrx[k] = DGNParseIEEE(temp1);
2040

    
2041
                                // nuevo m?todo
2042
                        }
2043

    
2044
                        System.arraycopy(pabyRawView, 106, temp1, 0, 8);
2045
                        fin[0] = 0;
2046
                        psTCB.views[iView].conversion = ByteUtils.bytesToLong(temp1, fin);
2047
                        fin[0] = 0;
2048
                        psTCB.views[iView].conversion = ByteUtils.bytesToDouble(temp1, fin);
2049

    
2050
                        // memcpy( (psTCB.views[iView].conversion), pabyRawView + 106,
2051
                        // sizeof(double) );
2052
                        DGNParseIEEE(psTCB.views[iView].conversion);
2053
                        System.arraycopy(pabyRawView, 114, temp1, 0, 8);
2054
                        psTCB.views[iView].activez = DGN_INT32(temp1);
2055
                }
2056

    
2057
                // DGNDumpElement(psDGN, psTCB,"");
2058
                return psTCB;
2059
        }
2060

    
2061
        /**
2062
         * Cambia un entero a LitterIndian.
2063
         * 
2064
         * @param x
2065
         *            Entero de entrada.
2066
         * 
2067
         * @return Entero de salida.
2068
         */
2069
        private int CPL_LSBWORD32(int x) {
2070
                return (((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)
2071
                                | (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24)));
2072
        }
2073

    
2074
        /**
2075
         * Cambia el vector de char de entrada en el caso de ser null por el
2076
         * caracter vacio.
2077
         * 
2078
         * @param pszString
2079
         *            Vector de char.
2080
         * 
2081
         * @return Vector de char.
2082
         */
2083
        private char[] CPLStrdup(char[] pszString) {
2084
                char[] pszReturn;
2085

    
2086
                if (pszString == null) {
2087
                        pszString[0] = ' ';
2088
                }
2089

    
2090
                pszReturn = new char[pszString.length];
2091

    
2092
                // pszReturn = VSIStrdup( pszString );
2093
                pszReturn = pszString;
2094

    
2095
                if (pszReturn == null) {
2096
                        System.out.println("error");
2097

    
2098
                        /*
2099
                         * CPLError( CE_Fatal, CPLE_OutOfMemory,
2100
                         * "CPLStrdup(): Out of memory allocating %d bytes.\n",
2101
                         * strlen(pszString) );
2102
                         */
2103
                }
2104

    
2105
                return (pszReturn);
2106
        }
2107

    
2108
        /**
2109
         * DOCUMENT ME!
2110
         * 
2111
         * @param psDGN
2112
         *            DOCUMENT ME!
2113
         * 
2114
         * @return DOCUMENT ME!
2115
         */
2116
        private DGNElemCore DGNParseTagSet(DGNInfo psDGN) {
2117
                // DGNElemCore psElement;
2118
                DGNElemTagSet psTagSet = new DGNElemTagSet();
2119
                int nDataOffset;
2120
                int iTag;
2121

    
2122
                // psTagSet = (DGNElemTagSet *) CPLCalloc(sizeof(DGNElemTagSet),1);
2123
                // psElement = (DGNElemCore *) psTagSet;
2124
                psTagSet.stype = DGNFileHeader.DGNST_TAG_SET;
2125

    
2126
                DGNParseCore(psDGN, psTagSet);
2127

    
2128
                /* -------------------------------------------------------------------- */
2129
                /* Parse the overall information. */
2130
                /* -------------------------------------------------------------------- */
2131
                psTagSet.tagCount = ByteUtils.byteToUnsignedInt(psDGN.abyElem[44])
2132
                                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[45]) * 256);
2133
                psTagSet.flags = ByteUtils.byteToUnsignedInt(psDGN.abyElem[46])
2134
                                + (ByteUtils.byteToUnsignedInt(psDGN.abyElem[47]) * 256);
2135

    
2136
                int[] fin = new int[1];
2137
                fin[0] = 0;
2138

    
2139
                byte[] temp = new byte[elemento.attr_bytes];
2140
                System.arraycopy(psDGN.abyElem, 48, temp, 0, psDGN.abyElem.length - 48);
2141

    
2142
                psTagSet.tagSetName = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2143
                                .toCharArray());
2144

    
2145
                /* -------------------------------------------------------------------- */
2146
                /* Get the tag set number out of the attributes, if available. */
2147
                /* -------------------------------------------------------------------- */
2148
                psTagSet.tagSet = -1;
2149

    
2150
                if ((psTagSet.attr_bytes >= 8)
2151
                                && (psTagSet.attr_data[0] == (byte) 0x03)
2152
                                && (psTagSet.attr_data[1] == (byte) 0x10)
2153
                                && (psTagSet.attr_data[2] == (byte) 0x2f)
2154
                                && (psTagSet.attr_data[3] == (byte) 0x7d)) {
2155
                        psTagSet.tagSet = psTagSet.attr_data[4]
2156
                                        + (psTagSet.attr_data[5] * 256);
2157
                }
2158

    
2159
                /* -------------------------------------------------------------------- */
2160
                /* Parse each of the tag definitions. */
2161
                /* -------------------------------------------------------------------- */
2162
                // psTagSet.tagList = (DGNTagDef *) CPLMalloc(sizeof(DGNTagDef) *
2163
                // psTagSet->tagCount);
2164
                nDataOffset = 48 + psTagSet.tagSetName.length + 1 + 1;
2165

    
2166
                for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2167
                        DGNTagDef tagDef = new DGNTagDef();
2168

    
2169
                        // = psTagSet.tagList + iTag;
2170
                        tagDef.id = iTag;
2171

    
2172
                        // CPLAssert( nDataOffset < psDGN.nElemBytes );
2173
                        /* collect tag name. */
2174
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2175
                                        psDGN.abyElem.length);
2176
                        fin[0] = 0;
2177
                        tagDef.name = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2178
                                        .toCharArray());
2179
                        nDataOffset += ((tagDef.name.length) + 1);
2180

    
2181
                        /* Get tag id */
2182
                        tagDef.id = ByteUtils.byteToUnsignedInt(psDGN.abyElem[nDataOffset])
2183
                                        + (ByteUtils
2184
                                                        .byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2185
                        nDataOffset += 2;
2186

    
2187
                        /* Get User Prompt */
2188
                        System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2189
                                        psDGN.abyElem.length);
2190
                        fin[0] = 0;
2191
                        tagDef.prompt = CPLStrdup(ByteUtils.bytesToString(temp, fin)
2192
                                        .toCharArray());
2193
                        nDataOffset += ((tagDef.prompt.length) + 1);
2194

    
2195
                        /* Get type */
2196
                        tagDef.type = ByteUtils
2197
                                        .byteToUnsignedInt(psDGN.abyElem[nDataOffset])
2198
                                        + (ByteUtils
2199
                                                        .byteToUnsignedInt(psDGN.abyElem[nDataOffset + 1]) * 256);
2200
                        nDataOffset += 2;
2201

    
2202
                        /* skip five zeros */
2203
                        nDataOffset += 5;
2204

    
2205
                        /* Get the default */
2206
                        if (tagDef.type == 1) {
2207
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0,
2208
                                                psDGN.abyElem.length);
2209
                                fin[0] = 0;
2210
                                tagDef.defaultValue.string = CPLStrdup(ByteUtils.bytesToString(
2211
                                                temp, fin).toCharArray());
2212
                                nDataOffset += (tagDef.defaultValue.string.length + 1);
2213
                        } else if ((tagDef.type == 3) || (tagDef.type == 5)) {
2214
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 4);
2215
                                fin[0] = 0;
2216
                                tagDef.defaultValue.integer = ByteUtils.bytesToLong(temp, fin);
2217

    
2218
                                // memcpy( (tagDef.defaultValue.integer),psDGN.abyElem +
2219
                                // nDataOffset, 4 );
2220
                                tagDef.defaultValue.integer = CPL_LSBWORD32((int) tagDef.defaultValue.integer);
2221
                                nDataOffset += 4;
2222
                        } else if (tagDef.type == 4) {
2223
                                System.arraycopy(psDGN.abyElem, nDataOffset, temp, 0, 8);
2224
                                fin[0] = 0;
2225
                                tagDef.defaultValue.real = ByteUtils.bytesToDouble(temp, fin);
2226

    
2227
                                // memcpy( (tagDef.defaultValue.real), psDGN.abyElem +
2228
                                // nDataOffset, 8 );
2229
                                DGNParseIEEE(tagDef.defaultValue.real);
2230
                                nDataOffset += 8;
2231
                        } else {
2232
                                nDataOffset += 4;
2233
                        }
2234
                }
2235

    
2236
                return psTagSet;
2237
        }
2238

    
2239
        /**
2240
         * DOCUMENT ME!
2241
         * 
2242
         * @param psDGN
2243
         *            DOCUMENT ME!
2244
         * @param nOptions
2245
         *            DOCUMENT ME!
2246
         */
2247
        private void DGNSetOptions(DGNInfo psDGN, int nOptions) {
2248
                psDGN.options = nOptions;
2249
        }
2250

    
2251
        /**
2252
         * DOCUMENT ME!
2253
         * 
2254
         * @param psDGN
2255
         *            DOCUMENT ME!
2256
         * @param dfXMin
2257
         *            DOCUMENT ME!
2258
         * @param dfYMin
2259
         *            DOCUMENT ME!
2260
         * @param dfXMax
2261
         *            DOCUMENT ME!
2262
         * @param dfYMax
2263
         *            DOCUMENT ME!
2264
         */
2265
        private void DGNSetSpatialFilter(DGNInfo psDGN, double dfXMin,
2266
                        double dfYMin, double dfXMax, double dfYMax) {
2267
                if ((dfXMin == 0.0) && (dfXMax == 0.0) && (dfYMin == 0.0)
2268
                                && (dfYMax == 0.0)) {
2269
                        psDGN.has_spatial_filter = FALSE;
2270

    
2271
                        return;
2272
                }
2273

    
2274
                psDGN.has_spatial_filter = TRUE;
2275
                psDGN.sf_converted_to_uor = FALSE;
2276

    
2277
                psDGN.sf_min_x_geo = dfXMin;
2278
                psDGN.sf_min_y_geo = dfYMin;
2279
                psDGN.sf_max_x_geo = dfXMax;
2280
                psDGN.sf_max_y_geo = dfYMax;
2281

    
2282
                DGNSpatialFilterToUOR(psDGN);
2283
        }
2284

    
2285
        /**
2286
         * Muestra por consola los elementos que contiene el DGN.
2287
         * 
2288
         * @param psInfo
2289
         *            Informaci?n del DGN.
2290
         * @param psElement
2291
         *            elemento
2292
         * @param fp
2293
         *            path del fichero.
2294
         */
2295
        public void DGNDumpElement(DGNInfo psInfo, DGNElemCore psElement, String fp) {
2296
                // DGNInfo *psInfo = (DGNInfo *) hDGN;
2297
                // System.out.println("\n");
2298
                System.out.println("Element:" + DGNTypeToName(psElement.type)
2299
                                + " Level:" + psElement.level + " id:" + psElement.element_id);
2300

    
2301
                if (psElement.complex != 0) {
2302
                        System.out.println("(Complex) ");
2303
                }
2304

    
2305
                if (psElement.deleted != 0) {
2306
                        System.out.println("(DELETED) ");
2307
                }
2308

    
2309
                System.out.println("  offset=" + psElement.offset + " size="
2310
                                + psElement.size + " bytes\n");
2311

    
2312
                System.out.println("  graphic_group:" + psElement.graphic_group
2313
                                + " color:" + psElement.color + " weight:" + psElement.weight
2314
                                + "style:" + psElement.style + "\n");
2315

    
2316
                if (psElement.properties != 0) {
2317
                        int nClass;
2318

    
2319
                        System.out.println("  properties=" + psElement.properties);
2320

    
2321
                        if ((psElement.properties & DGNFileHeader.DGNPF_HOLE) != 0) {
2322
                                System.out.println(",HOLE");
2323
                        }
2324

    
2325
                        if ((psElement.properties & DGNFileHeader.DGNPF_SNAPPABLE) != 0) {
2326
                                System.out.println(",SNAPPABLE");
2327
                        }
2328

    
2329
                        if ((psElement.properties & DGNFileHeader.DGNPF_PLANAR) != 0) {
2330
                                System.out.println(",PLANAR");
2331
                        }
2332

    
2333
                        if ((psElement.properties & DGNFileHeader.DGNPF_ORIENTATION) != 0) {
2334
                                System.out.println(",ORIENTATION");
2335
                        }
2336

    
2337
                        if ((psElement.properties & DGNFileHeader.DGNPF_ATTRIBUTES) != 0) {
2338
                                System.out.println(",ATTRIBUTES");
2339
                        }
2340

    
2341
                        if ((psElement.properties & DGNFileHeader.DGNPF_MODIFIED) != 0) {
2342
                                System.out.println(",MODIFIED");
2343
                        }
2344

    
2345
                        if ((psElement.properties & DGNFileHeader.DGNPF_NEW) != 0) {
2346
                                System.out.println(",NEW");
2347
                        }
2348

    
2349
                        if ((psElement.properties & DGNFileHeader.DGNPF_LOCKED) != 0) {
2350
                                System.out.println(",LOCKED");
2351
                        }
2352

    
2353
                        nClass = psElement.properties & DGNFileHeader.DGNPF_CLASS;
2354

    
2355
                        if (nClass == DGNFileHeader.DGNC_PATTERN_COMPONENT) {
2356
                                System.out.println(",PATTERN_COMPONENT");
2357
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_ELEMENT) {
2358
                                System.out.println(",CONSTRUCTION ELEMENT");
2359
                        } else if (nClass == DGNFileHeader.DGNC_DIMENSION_ELEMENT) {
2360
                                System.out.println(",DIMENSION ELEMENT");
2361
                        } else if (nClass == DGNFileHeader.DGNC_PRIMARY_RULE_ELEMENT) {
2362
                                System.out.println(",PRIMARY RULE ELEMENT");
2363
                        } else if (nClass == DGNFileHeader.DGNC_LINEAR_PATTERNED_ELEMENT) {
2364
                                System.out.println(",LINEAR PATTERNED ELEMENT");
2365
                        } else if (nClass == DGNFileHeader.DGNC_CONSTRUCTION_RULE_ELEMENT) {
2366
                                System.out.println(",CONSTRUCTION_RULE_ELEMENT");
2367
                        }
2368

    
2369
                        // System.out.println("\n");
2370
                }
2371

    
2372
                switch (psElement.stype) {
2373
                case DGNFileHeader.DGNST_MULTIPOINT: {
2374
                        DGNElemMultiPoint psLine = new DGNElemMultiPoint();
2375
                        psLine = (DGNElemMultiPoint) psElement;
2376

    
2377
                        int i;
2378

    
2379
                        for (i = 0; i < psLine.num_vertices; i++) {
2380
                                System.out.println(psLine.vertices[i].x + ","
2381
                                                + psLine.vertices[i].y + "," + psLine.vertices[i].z);
2382
                        }
2383
                }
2384

    
2385
                        break;
2386

    
2387
                case DGNFileHeader.DGNST_CELL_HEADER: {
2388
                        DGNElemCellHeader psCell = new DGNElemCellHeader();
2389
                        psCell = (DGNElemCellHeader) psElement;
2390

    
2391
                        System.out.println("  totlength=" + psCell.totlength + ", name="
2392
                                        + psCell.name.toString() + " class=" + psCell.cclass
2393
                                        + " levels=" + psCell.levels[0] + psCell.levels[1]
2394
                                        + psCell.levels[2] + psCell.levels[3] + "\n");
2395
                        System.out.println("  rnglow=(" + psCell.rnglow.x + ","
2396
                                        + psCell.rnglow.y + "), rnghigh=(" + psCell.rnghigh.x + ","
2397
                                        + psCell.rnghigh.y + ")\n");
2398
                        System.out.println("  origin=(" + psCell.origin.x + ","
2399
                                        + psCell.origin.y + ")\n");
2400
                        System.out.println("  xscale=" + psCell.xscale + ",yscale="
2401
                                        + psCell.yscale + ", rotation=" + psCell.rotation + "\n");
2402
                }
2403

    
2404
                        break;
2405

    
2406
                case DGNFileHeader.DGNST_CELL_LIBRARY: {
2407
                        DGNElemCellLibrary psCell = new DGNElemCellLibrary();
2408
                        psCell = (DGNElemCellLibrary) psElement;
2409

    
2410
                        System.out.println("  name=" + psCell.name.toString() + " class="
2411
                                        + psCell.cclass + " levels=" + psCell.levels[0]
2412
                                        + psCell.levels[1] + psCell.levels[2] + psCell.levels[3]
2413
                                        + " numwords=" + psCell.numwords + "\n");
2414
                        System.out.println("  dispsymb=" + psCell.dispsymb
2415
                                        + ", description=" + psCell.description + "\n");
2416
                }
2417

    
2418
                        break;
2419

    
2420
                case DGNFileHeader.DGNST_ARC: {
2421
                        DGNElemArc psArc = new DGNElemArc();
2422
                        psArc = (DGNElemArc) psElement;
2423

    
2424
                        if (psInfo.dimension == 2) {
2425
                                System.out.println("  origin=(" + psArc.origin.x + ","
2426
                                                + psArc.origin.y + "), rotation=" + psArc.rotation
2427
                                                + "\n");
2428
                        } else {
2429
                                System.out.println("  origin=(" + psArc.origin.x + ","
2430
                                                + psArc.origin.y + "," + psArc.origin.z + "), quat="
2431
                                                + psArc.quat[0] + "," + psArc.quat[1] + ","
2432
                                                + psArc.quat[2] + "," + psArc.quat[3] + "\n");
2433
                        }
2434

    
2435
                        System.out.println("  axes=(" + psArc.primary_axis + ","
2436
                                        + psArc.secondary_axis + "), start angle=" + psArc.startang
2437
                                        + ", sweep=" + psArc.sweepang + "\n");
2438
                }
2439

    
2440
                        break;
2441

    
2442
                case DGNFileHeader.DGNST_TEXT: {
2443
                        DGNElemText psText = new DGNElemText();
2444
                        psText = (DGNElemText) psElement;
2445

    
2446
                        System.out.println("  origin=(" + psText.origin.x + psText.origin.y
2447
                                        + ") rotation=" + psText.rotation + "\n" + "  font="
2448
                                        + psText.font_id + " just=" + psText.justification
2449
                                        + "length_mult=" + psText.length_mult + " height_mult="
2450
                                        + psText.height_mult + "\n" + "  string ="
2451
                                        + new String(psText.string).toString() + "\n");
2452
                }
2453

    
2454
                        break;
2455

    
2456
                case DGNFileHeader.DGNST_COMPLEX_HEADER: {
2457
                        DGNElemComplexHeader psHdr = new DGNElemComplexHeader();
2458
                        psHdr = (DGNElemComplexHeader) psElement;
2459

    
2460
                        System.out.println("  totlength=" + psHdr.totlength + "numelems="
2461
                                        + psHdr.numelems + "\n");
2462
                }
2463

    
2464
                        break;
2465

    
2466
                case DGNFileHeader.DGNST_COLORTABLE: {
2467
                        DGNElemColorTable psCT = new DGNElemColorTable();
2468
                        psCT = (DGNElemColorTable) psElement;
2469

    
2470
                        int i;
2471

    
2472
                        System.out.println("  screen_flag:" + psCT.screen_flag + "\n");
2473

    
2474
                        for (i = 0; i < 256; i++) {
2475
                                System.out.println(i + ": (" + psCT.color_info[i][0] + ","
2476
                                                + psCT.color_info[i][1] + "," + psCT.color_info[i][2]
2477
                                                + ")\n");
2478
                        }
2479
                }
2480

    
2481
                        break;
2482

    
2483
                case DGNFileHeader.DGNST_TCB: {
2484
                        DGNElemTCB psTCB = new DGNElemTCB();
2485
                        psTCB = (DGNElemTCB) psElement;
2486

    
2487
                        int iView;
2488

    
2489
                        // psTCB.dimension=psInfo.dimension;
2490
                        System.out.println("  dimension =" + psTCB.dimension + "\n");
2491
                        System.out.println("  uor_per_subunit =" + psTCB.uor_per_subunit); // +
2492

    
2493
                        // " subunits = `" + psTCB.sub_units[0] + psTCB.sub_units[1] +
2494
                        // psTCB.sub_units[2] + "'\n");
2495
                        System.out.println("  subunits_per_master ="
2496
                                        + psTCB.subunits_per_master); // + " master_units = `" +
2497

    
2498
                        // psTCB.master_units[0] + psTCB.master_units[1] +
2499
                        // psTCB.master_units[2] + "'\n");
2500
                        System.out.println("  origin = (" + psTCB.origin_x + ","
2501
                                        + psTCB.origin_y + "," + psTCB.origin_z + ")\n");
2502

    
2503
                        for (iView = 0; iView < 8; iView++) {
2504
                                DGNViewInfo psView = psTCB.views[iView];
2505

    
2506
                                // DGNParseTCB(psInfo);
2507
                                System.out.println("View  " + iView + ": flags= "
2508
                                                + Integer.toHexString(psView.flags) + " levels= "
2509
                                                + psView.levels[0] + "" + psView.levels[1] + ""
2510
                                                + psView.levels[2] + "" + psView.levels[3] + ""
2511
                                                + psView.levels[4] + "" + psView.levels[5] + ""
2512
                                                + psView.levels[6] + "" + psView.levels[7] + "\n");
2513
                                System.out.println("origin=( " + psView.origin.x + ","
2514
                                                + psView.origin.y + "," + psView.origin.z
2515
                                                + ")\n        delta=(" + psView.delta.x + ","
2516
                                                + psView.delta.y + "," + psView.delta.z + ")\n");
2517

    
2518
                                System.out.println("trans=( " + psView.transmatrx[0] + ","
2519
                                                + psView.transmatrx[1] + "," + psView.transmatrx[2]
2520
                                                + "," + psView.transmatrx[3] + ","
2521
                                                + psView.transmatrx[4] + "," + psView.transmatrx[5]
2522
                                                + "," + psView.transmatrx[6] + ","
2523
                                                + psView.transmatrx[7] + "," + psView.transmatrx[8]
2524
                                                + ")\n");
2525
                        }
2526
                }
2527

    
2528
                        break;
2529

    
2530
                case DGNFileHeader.DGNST_TAG_SET: {
2531
                        DGNElemTagSet psTagSet = new DGNElemTagSet();
2532
                        psTagSet = (DGNElemTagSet) psElement;
2533

    
2534
                        int iTag;
2535

    
2536
                        System.out.println("  tagSetName=" + psTagSet.tagSetName.toString()
2537
                                        + " tagSet=" + psTagSet.tagSet + " tagCount="
2538
                                        + psTagSet.tagCount + " flags=" + psTagSet.flags + "\n");
2539

    
2540
                        for (iTag = 0; iTag < psTagSet.tagCount; iTag++) {
2541
                                DGNTagDef psTagDef = psTagSet.tagList[iTag];
2542

    
2543
                                System.out.println(psTagDef.id + ": name="
2544
                                                + psTagDef.name.toString() + ", type=" + psTagDef.type
2545
                                                + ", prompt=" + psTagDef.prompt.toString());
2546

    
2547
                                if (psTagDef.type == 1) {
2548
                                        System.out.println(", default="
2549
                                                        + psTagDef.defaultValue.string.toString() + "\n");
2550
                                } else if ((psTagDef.type == 3) || (psTagDef.type == 5)) {
2551
                                        System.out.println(", default="
2552
                                                        + psTagDef.defaultValue.integer + "\n");
2553
                                } else if (psTagDef.type == 4) {
2554
                                        System.out.println(", default="
2555
                                                        + psTagDef.defaultValue.real + "\n");
2556
                                } else {
2557
                                        System.out.println(", default=<unknown>\n");
2558
                                }
2559
                        }
2560
                }
2561

    
2562
                        break;
2563

    
2564
                case DGNFileHeader.DGNST_TAG_VALUE: {
2565
                        DGNElemTagValue psTag = new DGNElemTagValue();
2566
                        psTag = (DGNElemTagValue) psElement;
2567

    
2568
                        System.out.println("  tagType=" + psTag.tagType + ", tagSet="
2569
                                        + psTag.tagSet + ", tagIndex=" + psTag.tagIndex
2570
                                        + ", tagLength=" + psTag.tagLength + "\n");
2571

    
2572
                        if (psTag.tagType == 1) {
2573
                                System.out.println("  value="
2574
                                                + psTag.tagValue.string.toString() + "\n");
2575
                        } else if (psTag.tagType == 3) {
2576
                                System.out.println("  value=" + psTag.tagValue.integer + "\n");
2577
                        } else if (psTag.tagType == 4) {
2578
                                System.out.println("  value=" + psTag.tagValue.real + "\n");
2579
                        }
2580
                }
2581

    
2582
                        break;
2583

    
2584
                case DGNFileHeader.DGNST_GROUP_DATA: {
2585
                        // TODO
2586
                }
2587

    
2588
                        break;
2589

    
2590
                default:
2591
                        break;
2592
                }
2593

    
2594
                if (psElement.attr_bytes > 0) {
2595
                        int iLink;
2596

    
2597
                        System.out.println("Attributes:" + psElement.attr_bytes + "\n");
2598

    
2599
                        for (iLink = 0; true; iLink++) {
2600
                                int[] nLinkType = new int[1];
2601
                                int[] nEntityNum = new int[1];
2602
                                int[] nMSLink = new int[1];
2603
                                int[] nLinkSize = new int[1];
2604
                                int i;
2605
                                nEntityNum[0] = 0;
2606
                                nMSLink[0] = 0;
2607

    
2608
                                byte[] pabyData;
2609

    
2610
                                pabyData = DGNGetLinkage(psInfo, psElement, iLink, nLinkType,
2611
                                                nEntityNum, nMSLink, nLinkSize);
2612

    
2613
                                if (pabyData == null) {
2614
                                        break;
2615
                                }
2616

    
2617
                                System.out.println("Type=0x" + nLinkType);
2618

    
2619
                                if ((nMSLink[0] != 0) || (nEntityNum[0] != 0)) {
2620
                                        System.out.println(", EntityNum=" + nEntityNum[0]
2621
                                                        + ", MSLink=" + nMSLink[0]);
2622
                                }
2623

    
2624
                                System.out.println("\n  0x");
2625

    
2626
                                for (i = 0; i < nLinkSize[0]; i++) {
2627
                                        System.out.println(pabyData[i]);
2628
                                }
2629

    
2630
                                System.out.println("\n");
2631
                        }
2632
                }
2633
        }
2634

    
2635
        /**
2636
         * Returns requested linkage raw data. A pointer to the raw data for the
2637
         * requested attribute linkage is returned as well as (potentially) various
2638
         * information about the linkage including the linkage type, database entity
2639
         * number and MSLink value, and the length of the raw linkage data in bytes.
2640
         * If the requested linkage (iIndex) does not exist a value of zero is
2641
         * returned. The entity number is (loosely speaking) the index of the table
2642
         * within the current database to which the MSLINK value will refer. The
2643
         * entity number should be used to lookup the table name in the MSCATALOG
2644
         * table. The MSLINK value is the key value for the record in the target
2645
         * table.
2646
         * 
2647
         * @param psDGN
2648
         *            the file from which the element originated.
2649
         * @param psElement
2650
         *            the element to report on.
2651
         * @param iIndex
2652
         *            the zero based index of the linkage to fetch.
2653
         * @param pnLinkageType
2654
         *            variable to return linkage type. This may be one of the
2655
         *            predefined DGNLT_ values or a different value. This pointer
2656
         *            may be NULL.
2657
         * @param pnEntityNum
2658
         *            variable to return the entity number in or NULL if not
2659
         *            required.
2660
         * @param pnMSLink
2661
         *            variable to return the MSLINK value in, or NULL if not
2662
         *            required.
2663
         * @param pnLength
2664
         *            variable to returned the linkage size in bytes or NULL.
2665
         * 
2666
         * @return pointer to raw internal linkage data. This data should not be
2667
         *         altered or freed. NULL returned on failure.
2668
         */
2669
        private byte[] DGNGetLinkage(DGNInfo psDGN, DGNElemCore psElement,
2670
                        int iIndex, int[] pnLinkageType, int[] pnEntityNum, int[] pnMSLink,
2671
                        int[] pnLength) {
2672
                int nAttrOffset;
2673
                int iLinkage;
2674
                int nLinkSize;
2675

    
2676
                for (iLinkage = 0, nAttrOffset = 0; (nLinkSize = DGNGetAttrLinkSize(
2677
                                psDGN, psElement, nAttrOffset)) != 0; iLinkage++, nAttrOffset += nLinkSize) {
2678
                        if (iLinkage == iIndex) {
2679
                                int nLinkageType = 0;
2680
                                int nEntityNum = 0;
2681
                                int nMSLink = 0;
2682

    
2683
                                // CPLAssert( nLinkSize > 4 );
2684
                                if ((psElement.attr_data[nAttrOffset + 0] == (byte) 0x00)
2685
                                                && ((psElement.attr_data[nAttrOffset + 1] == (byte) 0x00) || (psElement.attr_data[nAttrOffset + 1] == (byte) 0x80))) {
2686
                                        nLinkageType = DGNFileHeader.DGNLT_DMRS;
2687
                                        nEntityNum = psElement.attr_data[nAttrOffset + 2]
2688
                                                        + (psElement.attr_data[nAttrOffset + 3] * 256);
2689
                                        nMSLink = psElement.attr_data[nAttrOffset + 4]
2690
                                                        + (psElement.attr_data[nAttrOffset + 5] * 256)
2691
                                                        + (psElement.attr_data[nAttrOffset + 6] * 65536);
2692
                                } else {
2693
                                        nLinkageType = psElement.attr_data[nAttrOffset + 2]
2694
                                                        + (psElement.attr_data[nAttrOffset + 3] * 256);
2695
                                }
2696

    
2697
                                // Possibly an external database linkage?
2698
                                if ((nLinkSize == 16)
2699
                                                && (nLinkageType != DGNFileHeader.DGNLT_SHAPE_FILL)) {
2700
                                        nEntityNum = psElement.attr_data[nAttrOffset + 6]
2701
                                                        + (psElement.attr_data[nAttrOffset + 7] * 256);
2702
                                        nMSLink = psElement.attr_data[nAttrOffset + 8]
2703
                                                        + (psElement.attr_data[nAttrOffset + 9] * 256)
2704
                                                        + (psElement.attr_data[nAttrOffset + 10] * 65536)
2705
                                                        + (psElement.attr_data[nAttrOffset + 11] * 65536 * 256);
2706
                                }
2707

    
2708
                                if (pnLinkageType != null) {
2709
                                        pnLinkageType[0] = nLinkageType;
2710
                                }
2711

    
2712
                                if (pnEntityNum != null) {
2713
                                        pnEntityNum[0] = nEntityNum;
2714
                                }
2715

    
2716
                                if (pnMSLink != null) {
2717
                                        pnMSLink[0] = nMSLink;
2718
                                }
2719

    
2720
                                if (pnLength != null) {
2721
                                        pnLength[0] = nLinkSize;
2722
                                }
2723

    
2724
                                byte[] temp = new byte[psElement.attr_data.length - nAttrOffset];
2725
                                System.arraycopy(psElement.attr_data, nAttrOffset, temp, 0,
2726
                                                psElement.attr_data.length - nAttrOffset);
2727

    
2728
                                return temp;
2729
                        }
2730
                }
2731

    
2732
                return null;
2733
        }
2734

    
2735
        /**
2736
         * Devuelve el tama?o de los atributos de un elemento.
2737
         * 
2738
         * @param psDGN
2739
         *            Informaci?n del DGN.
2740
         * @param psElement
2741
         *            elemento.
2742
         * @param nOffset
2743
         *            indice donde se encuentra el elemento.
2744
         * 
2745
         * @return Entero que representa el Tama?o.
2746
         */
2747
        private int DGNGetAttrLinkSize(DGNInfo psDGN, DGNElemCore psElement,
2748
                        int nOffset) {
2749
                if (psElement.attr_bytes < (nOffset + 4)) {
2750
                        return 0;
2751
                }
2752

    
2753
                /* DMRS Linkage */
2754
                if (((psElement.attr_data[nOffset + 0] == 0) && (psElement.attr_data[nOffset + 1] == 0))
2755
                                || ((psElement.attr_data[nOffset + 0] == 0) && (psElement.attr_data[nOffset + 1] == (byte) 0x80))) {
2756
                        return 8;
2757
                }
2758

    
2759
                /* If low order bit of second byte is set, first byte is length */
2760
                if ((psElement.attr_data[nOffset + 1] & (byte) 0x10) != FALSE) {
2761
                        return (psElement.attr_data[nOffset + 0] * 2) + 2;
2762
                }
2763

    
2764
                /* unknown */
2765
                return 0;
2766
        }
2767

    
2768
        /**
2769
         * A partir de un entero devuelve el un String con el tipo del elemento.
2770
         * 
2771
         * @param nType
2772
         *            tipo.
2773
         * 
2774
         * @return String con el nombre del elemento.
2775
         */
2776
        private String DGNTypeToName(int nType) {
2777
                // char[] szNumericResult=new char[16];
2778
                switch (nType) {
2779
                case DGNFileHeader.DGNT_CELL_LIBRARY:
2780
                        return "Cell Library";
2781

    
2782
                case DGNFileHeader.DGNT_CELL_HEADER:
2783
                        return "Cell Header";
2784

    
2785
                case DGNFileHeader.DGNT_LINE:
2786
                        return "Line";
2787

    
2788
                case DGNFileHeader.DGNT_LINE_STRING:
2789
                        return "Line String";
2790

    
2791
                case DGNFileHeader.DGNT_GROUP_DATA:
2792
                        return "Group Data";
2793

    
2794
                case DGNFileHeader.DGNT_SHAPE:
2795
                        return "Shape";
2796

    
2797
                case DGNFileHeader.DGNT_TEXT_NODE:
2798
                        return "Text Node";
2799

    
2800
                case DGNFileHeader.DGNT_DIGITIZER_SETUP:
2801
                        return "Digitizer Setup";
2802

    
2803
                case DGNFileHeader.DGNT_TCB:
2804
                        return "TCB";
2805

    
2806
                case DGNFileHeader.DGNT_LEVEL_SYMBOLOGY:
2807
                        return "Level Symbology";
2808

    
2809
                case DGNFileHeader.DGNT_CURVE:
2810
                        return "Curve";
2811

    
2812
                case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
2813
                        return "Complex Chain Header";
2814

    
2815
                case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
2816
                        return "Complex Shape Header";
2817

    
2818
                case DGNFileHeader.DGNT_ELLIPSE:
2819
                        return "Ellipse";
2820

    
2821
                case DGNFileHeader.DGNT_ARC:
2822
                        return "Arc";
2823

    
2824
                case DGNFileHeader.DGNT_TEXT:
2825
                        return "Text";
2826

    
2827
                case DGNFileHeader.DGNT_BSPLINE:
2828
                        return "B-Spline";
2829

    
2830
                case DGNFileHeader.DGNT_APPLICATION_ELEM:
2831
                        return "Application Element";
2832

    
2833
                case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
2834
                        return "Shared Cell Definition";
2835

    
2836
                case DGNFileHeader.DGNT_SHARED_CELL_ELEM:
2837
                        return "Shared Cell Element";
2838

    
2839
                case DGNFileHeader.DGNT_TAG_VALUE:
2840
                        return "Tag Value";
2841

    
2842
                default:
2843
                        System.out.println(nType);
2844

    
2845
                        return "Fallo";
2846
                }
2847
        }
2848

    
2849
        /**
2850
         * Muestra por consola la fila de un elemento.
2851
         * 
2852
         * @param psDGN
2853
         *            informaci?n del DGN.
2854
         * @param psCore
2855
         *            elemento
2856
         * @param fpOut
2857
         *            path del fichero DGN.
2858
         */
2859
        private void DGNDumpRawElement(DGNInfo psDGN, DGNElemCore psCore,
2860
                        String fpOut) {
2861
                int i;
2862
                int iChar = 0;
2863
                byte[] szLine = new byte[80];
2864

    
2865
                // System.out.println("  Raw Data (" + psCore.raw_bytes + " bytes):\n");
2866
                for (i = 0; i < psCore.raw_bytes; i++) {
2867
                        byte[] szHex = new byte[3];
2868

    
2869
                        if ((i % 16) == 0) {
2870
                                int[] f = new int[1];
2871
                                byte[] temp = new byte[4];
2872
                                f[0] = 0;
2873
                                ByteUtils.intToBytes(i, temp, f);
2874
                                System.arraycopy(temp, 0, szLine, 0, 4);
2875

    
2876
                                // //System.out.println( szLine.toString()+","+ i );
2877
                                iChar = 0;
2878
                        }
2879

    
2880
                        szHex[0] = psCore.raw_data[i];
2881
                        szHex[1] = (byte) 0x00;
2882

    
2883
                        // System.arraycopy(psCore.raw_data,0,szHex,0,3);
2884
                        // //System.out.println(
2885
                        // szHex.toString()+","+psCore.raw_data.toString() );
2886
                        // strncpy( szLine+8+iChar*2, szHex, 2 );/**no se */
2887
                        System.arraycopy(szHex, 0, szLine, 8 + (iChar * 2), 2);
2888

    
2889
                        if ((psCore.raw_data[i] < 32) || (psCore.raw_data[i] > 127)) {
2890
                                szLine[42 + iChar] = '.';
2891
                        } else {
2892
                                szLine[42 + iChar] = psCore.raw_data[i];
2893
                        }
2894

    
2895
                        if ((i == (psCore.raw_bytes - 1)) || (((i + 1) % 16) == 0)) {
2896
                                // //System.out.println(szLine.toString()+"\n" );
2897
                                int[] f = new int[1];
2898
                                f[0] = 0;
2899

    
2900
                                // ByteUtils.bytesToInt(szLine,f);
2901
                                // System.out.println(ByteUtils.bytesToInt(szLine, f) + " : ");
2902
                                // ByteUtils.print_bytes(szLine,8,74);
2903
                                byte[] temp = new byte[1];
2904
                                byte[] temp1 = new byte[16];
2905
                                int k = 0;
2906

    
2907
                                for (int j = 1; j < 32; j = j + 2) {
2908
                                        System.arraycopy(szLine, j + 7, temp, 0, 1);
2909
                                        temp1[k] = temp[0];
2910
                                        k++;
2911
                                }
2912

    
2913
                                // System.out.println(ByteUtils.print_bytes(temp1));
2914
                                // //System.out.println(ByteUtils.print_bytes(szLine,7,41));
2915
                                f[0] = 42;
2916

    
2917
                                char[] tempchar = new char[16];
2918

    
2919
                                for (int j = 0; j < 16; j++) {
2920
                                        tempchar[j] = (char) szLine[42 + j];
2921
                                }
2922

    
2923
                                // System.out.println(String.copyValueOf(tempchar));
2924
                        }
2925

    
2926
                        iChar++;
2927
                }
2928
        }
2929

    
2930
        /**
2931
         * Devuelve el extent del elemento.
2932
         * 
2933
         * @param psDGN
2934
         *            Informaci?n del DGN.
2935
         * @param padfExtents
2936
         *            doubles que representan el rect?ngulo del extent.
2937
         * 
2938
         * @return Entero que muestra si se ha calculado correctamente.
2939
         */
2940
        private int DGNGetExtents(DGNInfo psDGN, double[] padfExtents) {
2941
                // DGNInfo *psDGN = (DGNInfo *) hDGN;
2942
                DGNPoint sMin = new DGNPoint();
2943
                DGNPoint sMax = new DGNPoint();
2944

    
2945
                DGNBuildIndex(psDGN);
2946

    
2947
                if (psDGN.got_bounds == FALSE) {
2948
                        return FALSE;
2949
                }
2950

    
2951
                double minX = psDGN.min_x;
2952
                double minY = psDGN.min_y;
2953
                double minZ = psDGN.min_z;
2954
                System.out.println("psDGN.min" + " x= " + psDGN.min_x + " y= "
2955
                                + psDGN.min_y);
2956

    
2957
                if (minX < 0) {
2958
                        minX = minX + (2 * ((long) Integer.MAX_VALUE + 1));
2959
                        System.out.println("minX" + minX);
2960
                }
2961

    
2962
                if (minY < 0) {
2963
                        minY = minY + (2 * ((long) Integer.MAX_VALUE + 1));
2964
                        System.out.println("minY " + minY);
2965
                }
2966

    
2967
                if (minZ < 0) {
2968
                        minZ = minZ + (2 * ((long) Integer.MAX_VALUE + 1));
2969
                }
2970

    
2971
                sMin.x = minX - 2147483648.0;
2972
                sMin.y = minY - 2147483648.0;
2973
                sMin.z = minZ - 2147483648.0;
2974

    
2975
                DGNTransformPoint(psDGN, sMin);
2976

    
2977
                padfExtents[0] = sMin.x;
2978
                padfExtents[1] = sMin.y;
2979
                padfExtents[2] = sMin.z;
2980

    
2981
                double maxX = psDGN.max_x;
2982
                double maxY = psDGN.max_y;
2983
                double maxZ = psDGN.max_z;
2984

    
2985
                // System.out.println("psDGN.max"+
2986
                // " x= "+psDGN.max_x+" y= "+psDGN.max_y);
2987
                if (maxX < 0) {
2988
                        maxX = maxX + (2 * ((long) Integer.MAX_VALUE + 1));
2989

    
2990
                        // System.out.println("maxX"+maxX);
2991
                }
2992

    
2993
                if (maxY < 0) {
2994
                        maxY = maxY + (2 * ((long) Integer.MAX_VALUE + 1));
2995

    
2996
                        // System.out.println("maxY"+maxY);
2997
                }
2998

    
2999
                if (maxZ < 0) {
3000
                        maxZ = maxZ + (2 * ((long) Integer.MAX_VALUE + 1));
3001
                }
3002

    
3003
                sMax.x = maxX - 2147483648.0;
3004
                sMax.y = maxY - 2147483648.0;
3005
                sMax.z = maxZ - 2147483648.0;
3006

    
3007
                DGNTransformPoint(psDGN, sMax);
3008

    
3009
                padfExtents[3] = sMax.x;
3010
                padfExtents[4] = sMax.y;
3011
                padfExtents[5] = sMax.z;
3012

    
3013
                return TRUE;
3014
        }
3015

    
3016
        /**
3017
         * Construye un ?ndice al DGN.
3018
         * 
3019
         * @param psDGN
3020
         *            Informaci?n del DGN.
3021
         */
3022
        private void DGNBuildIndex(DGNInfo psDGN) {
3023
                DGNElemCore elemento = new DGNElemCore();
3024
                int nMaxElements;
3025
                int nType;
3026
                int nLevel;
3027
                long nLastOffset;
3028

    
3029
                if (psDGN.index_built != FALSE) {
3030
                        return;
3031
                }
3032

    
3033
                psDGN.index_built = TRUE;
3034

    
3035
                // DGNRewind( psDGN );
3036
                nMaxElements = 0;
3037

    
3038
                // nLastOffset = VSIFTell( psDGN.fp );
3039
                nLastOffset = bb.position(); // psDGN.ftall;
3040

    
3041
                while (DGNLoadRawElement(psDGN, elemento) != FALSE) {
3042
                        DGNElementInfo psEI; // = new DGNElementInfo();
3043

    
3044
                        if (psDGN.element_count == nMaxElements) {
3045
                                int oldMax = nMaxElements;
3046
                                nMaxElements = (int) (nMaxElements * 1.5) + 500;
3047

    
3048
                                DGNElementInfo[] nuevo = new DGNElementInfo[nMaxElements];
3049

    
3050
                                for (int i = 0; i < oldMax; i++) {
3051
                                        nuevo[i] = psDGN.element_index[i];
3052
                                }
3053

    
3054
                                psDGN.element_index = nuevo;
3055

    
3056
                                // psDGN.element_index = (DGNElementInfo *) CPLRealloc(
3057
                                // psDGN.element_index,
3058
                                // nMaxElements * sizeof(DGNElementInfo) );
3059
                        }
3060

    
3061
                        psDGN.element_index[psDGN.element_count] = new DGNElementInfo();
3062
                        psEI = psDGN.element_index[psDGN.element_count];
3063
                        psEI.level = elemento.level;
3064
                        psEI.type = elemento.type;
3065
                        psEI.flags = 0;
3066
                        psEI.offset = nLastOffset;
3067

    
3068
                        if ((psDGN.abyElem[0] * (byte) 0x80) == (byte) 0x80) {
3069
                                psEI.flags |= DGNFileHeader.DGNEIF_COMPLEX;
3070
                        }
3071

    
3072
                        if ((psDGN.abyElem[1] * (byte) 0x80) == (byte) 0x80) {
3073
                                psEI.flags |= DGNFileHeader.DGNEIF_DELETED;
3074
                        }
3075

    
3076
                        if ((elemento.type == DGNFileHeader.DGNT_LINE)
3077
                                        || (elemento.type == DGNFileHeader.DGNT_LINE_STRING)
3078
                                        || (elemento.type == DGNFileHeader.DGNT_SHAPE)
3079
                                        || (elemento.type == DGNFileHeader.DGNT_CURVE)
3080
                                        || (elemento.type == DGNFileHeader.DGNT_BSPLINE)) {
3081
                                psEI.stype = DGNFileHeader.DGNST_MULTIPOINT;
3082
                        } else if ((elemento.type == DGNFileHeader.DGNT_GROUP_DATA)
3083
                                        && (elemento.level == DGNFileHeader.DGN_GDL_COLOR_TABLE)) {
3084
                                DGNElemCore psCT = DGNParseColorTable(psDGN);
3085

    
3086
                                // DGNFreeElement( psDGN, psCT );
3087
                                System.err.println("TABLA DE COLORES!!");
3088
                                psEI.stype = DGNFileHeader.DGNST_COLORTABLE;
3089
                                m_colorTable = (DGNElemColorTable) psCT;
3090

    
3091
                                // DGNDumpElement(psDGN,psCT,"");
3092
                        } else if ((elemento.type == DGNFileHeader.DGNT_ELLIPSE)
3093
                                        || (elemento.type == DGNFileHeader.DGNT_ARC)) {
3094
                                psEI.stype = DGNFileHeader.DGNST_ARC;
3095
                        } else if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)
3096
                                        || (elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)) {
3097
                                psEI.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
3098
                        } else if (elemento.type == DGNFileHeader.DGNT_TEXT) {
3099
                                psEI.stype = DGNFileHeader.DGNST_TEXT;
3100
                        } else if (elemento.type == DGNFileHeader.DGNT_TAG_VALUE) {
3101
                                psEI.stype = DGNFileHeader.DGNST_TAG_VALUE;
3102
                        } else if (elemento.type == DGNFileHeader.DGNT_APPLICATION_ELEM) {
3103
                                if (elemento.level == 24) {
3104
                                        psEI.stype = DGNFileHeader.DGNST_TAG_SET;
3105
                                } else {
3106
                                        psEI.stype = DGNFileHeader.DGNST_CORE;
3107
                                }
3108
                        } else if (elemento.type == DGNFileHeader.DGNT_TCB) {
3109
                                DGNElemCore psTCB = DGNParseTCB(psDGN);
3110

    
3111
                                // DGNFreeElement( psDGN, psTCB );
3112
                                psEI.stype = DGNFileHeader.DGNST_TCB;
3113
                        } else {
3114
                                psEI.stype = DGNFileHeader.DGNST_CORE;
3115
                        }
3116

    
3117
                        // DGNInfo tempo = new DGNInfo();
3118
                        double[] anRegion;
3119

    
3120
                        if (((psEI.flags & DGNFileHeader.DGNEIF_DELETED) == FALSE)
3121
                                        & ((psEI.flags & DGNFileHeader.DGNEIF_COMPLEX) == FALSE)
3122
                                        & ((anRegion = DGNGetRawExtents(psDGN, null, elemento)) != null)) {
3123
                                // #ifdef notdef
3124
                                // System.out.println(
3125
                                // "element_count"+psDGN.element_count+"anRegion[]"+("xmin"+anRegion[0])+"xmax"+anRegion[1]+"ymin"+anRegion[3]+"ymax"+anRegion[4]+
3126
                                // 2147483648.0 );
3127
                                // #endif
3128

    
3129
                                /*
3130
                                 * double aux=0; if (anRegion[0]>anRegion[3]){ aux=anRegion[3];
3131
                                 * anRegion[3]=anRegion[0]; anRegion[0]=anRegion[3]; } if
3132
                                 * (anRegion[1]>anRegion[4]){ aux=anRegion[4];
3133
                                 * anRegion[4]=anRegion[1]; anRegion[1]=anRegion[4]; }
3134
                                 */
3135
                                if (psDGN.got_bounds != FALSE) {
3136
                                        psDGN.min_x = Math.min(psDGN.min_x, anRegion[0]);
3137
                                        psDGN.min_y = Math.min(psDGN.min_y, anRegion[1]);
3138
                                        psDGN.min_z = Math.min(psDGN.min_z, anRegion[2]);
3139
                                        psDGN.max_x = Math.max(psDGN.max_x, anRegion[3]);
3140
                                        psDGN.max_y = Math.max(psDGN.max_y, anRegion[4]);
3141
                                        psDGN.max_z = Math.max(psDGN.max_z, anRegion[5]);
3142
                                } else {
3143
                                        psDGN.min_x = anRegion[0];
3144
                                        psDGN.min_y = anRegion[1];
3145
                                        psDGN.min_z = anRegion[2];
3146
                                        psDGN.max_x = anRegion[3];
3147
                                        psDGN.max_y = anRegion[4];
3148
                                        psDGN.max_z = anRegion[5];
3149

    
3150
                                        // memcpy( (psDGN.min_x), anRegion, sizeof(long) * 6 );
3151
                                        psDGN.got_bounds = TRUE;
3152
                                }
3153

    
3154
                                // System.out.println("xmin"+anRegion[0]+"xmax"+anRegion[3]+"ymin"+anRegion[1]+"ymax"+anRegion[4]+
3155
                                // "      "+2147483648.0 );
3156
                        }
3157

    
3158
                        psDGN.element_count++;
3159

    
3160
                        // nLastOffset = VSIFTell( psDGN.fp );
3161
                        nLastOffset = bb.position(); // psDGN.ftall;
3162
                }
3163

    
3164
                // DGNRewind( psDGN );
3165
                psDGN.max_element_count = nMaxElements;
3166
        }
3167

    
3168
        /**
3169
         * Devuelve el rect?ngulo que representa el extent del elemento.
3170
         * 
3171
         * @param psDGN
3172
         *            informaci?n del DGN.
3173
         * @param psElement
3174
         *            elemento.
3175
         * @param psMin
3176
         *            punto m?nimo.
3177
         * @param psMax
3178
         *            punto m?ximo.
3179
         * 
3180
         * @return Entero para comprobar si se ha calculado correctamente.
3181
         */
3182
        private int DGNGetElementExtents(DGNInfo psDGN, DGNElemCore psElement,
3183
                        DGNPoint psMin, DGNPoint psMax) {
3184
                // DGNInfo *psDGN = (DGNInfo *) hDGN;
3185
                long[] anMin = new long[3];
3186
                long[] anMax = new long[3];
3187
                DGNInfo tempo = new DGNInfo();
3188
                double[] bResult;
3189

    
3190
                /* -------------------------------------------------------------------- */
3191
                /* Get the extents if we have raw data in the element, or */
3192
                /* loaded in the file buffer. */
3193
                /* -------------------------------------------------------------------- */
3194
                if (psElement.raw_data != null) {
3195
                        bResult = DGNGetRawExtents(psDGN, psElement.raw_data, psElement);
3196
                } else {
3197
                        if (psElement.element_id == (psDGN.next_element_id - 1)) {
3198
                                bResult = DGNGetRawExtents(psDGN, psDGN.abyElem, psElement);
3199
                        } else {
3200
                                /*
3201
                                 * CPLError(CE_Warning, CPLE_AppDefined,
3202
                                 * "DGNGetElementExtents() fails because the requested element\n"
3203
                                 * " does not have raw data available." );
3204
                                 */
3205
                                return FALSE;
3206
                        }
3207
                }
3208

    
3209
                if (bResult == null) {
3210
                        return FALSE;
3211
                }
3212

    
3213
                /* -------------------------------------------------------------------- */
3214
                /* Transform to user coordinate system and return. The offset */
3215
                /* is to convert from "binary offset" form to twos complement. */
3216
                /* -------------------------------------------------------------------- */
3217
                psMin.x = tempo.min_x - 2147483648.0;
3218
                psMin.y = tempo.min_y - 2147483648.0;
3219
                psMin.z = tempo.min_z - 2147483648.0;
3220

    
3221
                psMax.x = tempo.max_x - 2147483648.0;
3222
                psMax.y = tempo.max_y - 2147483648.0;
3223
                psMax.z = tempo.max_z - 2147483648.0;
3224

    
3225
                DGNTransformPoint(psDGN, psMin);
3226
                DGNTransformPoint(psDGN, psMax);
3227

    
3228
                return TRUE;
3229
        }
3230

    
3231
        /**
3232
         * Devuelve los ?ndices de los elementos del DGN.
3233
         * 
3234
         * @param psDGN
3235
         *            Informaci?n del DGN.
3236
         * @param pnElementCount
3237
         *            N?mero de elementos.
3238
         * 
3239
         * @return ?ndices.
3240
         */
3241
        private DGNElementInfo[] DGNGetElementIndex(DGNInfo psDGN,
3242
                        int[] pnElementCount) {
3243
                // DGNInfo *psDGN = (DGNInfo *) hDGN;
3244
                DGNBuildIndex(psDGN);
3245

    
3246
                if (pnElementCount[0] != -1) {
3247
                        pnElementCount[0] = psDGN.element_count;
3248
                }
3249

    
3250
                return psDGN.element_index;
3251
        }
3252

    
3253
        /************************************************************************/
3254
        /* DGNLookupColor() */
3255
        /************************************************************************/
3256

    
3257
        /**
3258
         * Translate color index into RGB values. If no color table has yet been
3259
         * encountered in the file a hard-coded "default" color table will be used.
3260
         * This seems to be what Microstation uses as a color table when there isn't
3261
         * one in a DGN file but I am not absolutely convinced it is appropriate.
3262
         * 
3263
         * @param color_index
3264
         *            the color index to lookup.
3265
         * 
3266
         * @return TRUE on success or FALSE on failure. May fail if color_index is
3267
         *         out of range.
3268
         */
3269
        public Color DGNLookupColor(int color_index) {
3270
                int r;
3271
                int g;
3272
                int b;
3273

    
3274
                if ((color_index < 0) || (color_index > 255)) {
3275
                        return null;
3276
                }
3277

    
3278
                if (info.got_color_table == 0) {
3279
                        r = abyDefaultPCT[color_index][0];
3280
                        g = abyDefaultPCT[color_index][1];
3281
                        b = abyDefaultPCT[color_index][2];
3282
                } else {
3283
                        r = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][0]);
3284
                        g = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][1]);
3285
                        b = ByteUtils.getUnsigned(m_colorTable.color_info[color_index][2]);
3286
                }
3287
                if ((r == 255) && (g == 255) && (b == 255)) {
3288
                        r = g = b = 0; // El color blanco lo devolvemos como negro.
3289
                }
3290

    
3291
                return new Color(r, g, b);
3292
        }
3293

    
3294
        /************************************************************************/
3295
        /* DGNGetShapeFillInfo() */
3296
        /************************************************************************/
3297

    
3298
        /**
3299
         * Fetch fill color for a shape. This method will check for a 0x0041 user
3300
         * attribute linkaged with fill color information for the element. If found
3301
         * the function returns TRUE, and places the fill color in pnColor,
3302
         * otherwise FALSE is returned and pnColor is not updated.
3303
         * 
3304
         * @param psElem
3305
         *            the element.
3306
         * 
3307
         * @return index of color on success or -1 on failure.
3308
         */
3309
        public int DGNGetShapeFillInfo(DGNElemCore psElem) {
3310
                int iLink;
3311
                int color_index = -1;
3312

    
3313
                for (iLink = 0; true; iLink++) {
3314
                        int[] nLinkType = new int[1];
3315
                        int[] nEntityNum = new int[1];
3316
                        int[] nMSLink = new int[1];
3317
                        int[] nLinkSize = new int[1];
3318
                        int i;
3319
                        nEntityNum[0] = 0;
3320
                        nMSLink[0] = 0;
3321

    
3322
                        byte[] pabyData;
3323

    
3324
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3325
                                        nEntityNum, nMSLink, nLinkSize);
3326

    
3327
                        if (pabyData == null) {
3328
                                return -1;
3329
                        }
3330

    
3331
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_SHAPE_FILL)
3332
                                        && (nLinkSize[0] >= 7)) {
3333
                                color_index = ByteUtils.getUnsigned(pabyData[8]);
3334

    
3335
                                break;
3336
                        }
3337
                }
3338

    
3339
                return color_index;
3340
        }
3341

    
3342
        /************************************************************************/
3343
        /* DGNGetAssocID() */
3344
        /************************************************************************/
3345

    
3346
        /**
3347
         * Fetch association id for an element. This method will check if an element
3348
         * has an association id, and if so returns it, otherwise returning -1.
3349
         * Association ids are kept as a user attribute linkage where present.
3350
         * 
3351
         * @param psElem
3352
         *            the element.
3353
         * 
3354
         * @return The id or -1 on failure.
3355
         */
3356
        int DGNGetAssocID(DGNElemCore psElem) {
3357
                int iLink;
3358

    
3359
                for (iLink = 0; true; iLink++) {
3360
                        int[] nLinkType = new int[1];
3361
                        int[] nEntityNum = new int[1];
3362
                        int[] nMSLink = new int[1];
3363
                        int[] nLinkSize = new int[1];
3364
                        int i;
3365
                        nEntityNum[0] = 0;
3366
                        nMSLink[0] = 0;
3367

    
3368
                        byte[] pabyData;
3369

    
3370
                        pabyData = DGNGetLinkage(info, psElem, iLink, nLinkType,
3371
                                        nEntityNum, nMSLink, nLinkSize);
3372

    
3373
                        if (pabyData == null) {
3374
                                return -1;
3375
                        }
3376

    
3377
                        if ((nLinkType[0] == DGNFileHeader.DGNLT_ASSOC_ID)
3378
                                        && (nLinkSize[0] >= 8)) {
3379
                                return ByteUtils.getUnsigned(pabyData[4])
3380
                                                + (ByteUtils.getUnsigned(pabyData[5]) * 256)
3381
                                                + (ByteUtils.getUnsigned(pabyData[6]) * 256 * 256)
3382
                                                + (ByteUtils.getUnsigned(pabyData[7]) * 256 * 256 * 256);
3383
                        }
3384
                }
3385
        }
3386
}