Revision 85

View differences:

org.gvsig.dgn/tags/org.gvsig.dgn-2.0.24/org.gvsig.dgn.provider/src/test/java/org/gvsig/fmap/dal/store/dgn/TestDGN.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22

  
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2008 IVER T.I. S.A.   {{Task}}
26
*/
27

  
28
package org.gvsig.fmap.dal.store.dgn;
29

  
30
import java.io.File;
31

  
32
import org.gvsig.fmap.dal.DataStoreParameters;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.BaseTestFeatureStore;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36

  
37
public class TestDGN extends BaseTestFeatureStore {
38

  
39
	public static final File file_prueba = new File(TestDGN.class.getResource(
40
			"data/prueba.dgn").getFile());
41
	
42
	/*
43
	 * (non-Javadoc)
44
	 *
45
	 * @see
46
	 * org.gvsig.fmap.dal.feature.BaseTestFeatureStore#getDefaultDataStoreParameters
47
	 * ()
48
	 */
49
	public DataStoreParameters getDefaultDataStoreParameters()
50
			throws DataException {
51
		DGNStoreParameters dgnParameters = null;
52

  
53
		dgnParameters = (DGNStoreParameters) dataManager
54
				.createStoreParameters(DGNStoreProvider.NAME);
55

  
56
		dgnParameters.setFile(file_prueba.getAbsolutePath());
57
		dgnParameters.setCRS("EPSG:23030");
58
		return dgnParameters;
59
	}
60

  
61
	/*
62
	 * (non-Javadoc)
63
	 *
64
	 * @see org.gvsig.fmap.dal.feature.BaseTestFeatureStore#hasExplorer()
65
	 */
66
	public boolean hasExplorer() {
67
		// TODO Auto-generated method stub
68
		return false;
69
	}
70

  
71
	public boolean usesResources() {
72
		return true;
73
	}
74

  
75

  
76
	public void testLegendAndLabeling() throws Exception {
77
		FeatureStore store = (FeatureStore) dataManager
78
				.createStore(getDefaultDataStoreParameters());
79

  
80
		assertNotNull(store.invokeDynMethod("getLegend", null));
81
		assertNotNull(store.invokeDynMethod("getLabeling", null));
82
		store.dispose();
83
	}
84
}
org.gvsig.dgn/tags/org.gvsig.dgn-2.0.24/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/LegendBuilder.java
1
package org.gvsig.fmap.dal.store.dgn;
2

  
3
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
4
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
5
import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
6

  
7

  
8
public interface LegendBuilder {
9

  
10
	final public static String DYNMETHOD_BUILDER_NAME = "getLegendBuilder";
11
	final public static String DYNMETHOD_GETLEGEND_NAME = "getLegend";
12
	final public static String DYNMETHOD_GETLABELING_NAME = "getLabeling";
13

  
14
	public LegendBuilder initialize(FeatureStoreProvider store);
15

  
16
	public void begin();
17

  
18
	public void process(FeatureProvider feature, DGNReader dgnReader);
19

  
20
	public void end();
21

  
22
	public Object getLegend();
23
	public Object getLabeling();
24

  
25
}
org.gvsig.dgn/tags/org.gvsig.dgn-2.0.24/org.gvsig.dgn.provider/src/main/java/org/gvsig/fmap/dal/store/dgn/lib/DGNReader.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.store.dgn.lib;
24

  
25
import java.awt.Color;
26
import java.awt.geom.Rectangle2D;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.nio.ByteBuffer;
30
import java.nio.ByteOrder;
31
import java.nio.MappedByteBuffer;
32
import java.nio.channels.FileChannel;
33
import java.text.MessageFormat;
34
import java.util.ArrayList;
35
import java.util.Formatter;
36
import java.util.Iterator;
37
import java.util.LinkedHashMap;
38
import java.util.List;
39
import java.util.Map;
40

  
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.exception.ReadException;
43
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
45

  
46
/**
47
 * Clase dedicada a leer del fichero DGN.
48
 *
49
 */
50
public class DGNReader {
51

  
52
    private static Logger logger = LoggerFactory.getLogger(DGNReader.class);
53
    static int[][] abyDefaultPCT = {{255, 255, 255}, {0, 0, 255},
54
    {0, 255, 0}, {255, 0, 0}, {255, 255, 0}, {255, 0, 255},
55
    {255, 127, 0}, {0, 255, 255}, {64, 64, 64},
56
    {192, 192, 192}, {254, 0, 96}, {160, 224, 0},
57
    {0, 254, 160}, {128, 0, 160}, {176, 176, 176},
58
    {0, 240, 240}, {240, 240, 240}, {0, 0, 240}, {0, 240, 0},
59
    {240, 0, 0}, {240, 240, 0}, {240, 0, 240}, {240, 122, 0},
60
    {0, 240, 240}, {240, 240, 240}, {0, 0, 240}, {0, 240, 0},
61
    {240, 0, 0}, {240, 240, 0}, {240, 0, 240}, {240, 122, 0},
62
    {0, 225, 225}, {225, 225, 225}, {0, 0, 225}, {0, 225, 0},
63
    {225, 0, 0}, {225, 225, 0}, {225, 0, 225}, {225, 117, 0},
64
    {0, 225, 225}, {225, 225, 225}, {0, 0, 225}, {0, 225, 0},
65
    {225, 0, 0}, {225, 225, 0}, {225, 0, 225}, {225, 117, 0},
66
    {0, 210, 210}, {210, 210, 210}, {0, 0, 210}, {0, 210, 0},
67
    {210, 0, 0}, {210, 210, 0}, {210, 0, 210}, {210, 112, 0},
68
    {0, 210, 210}, {210, 210, 210}, {0, 0, 210}, {0, 210, 0},
69
    {210, 0, 0}, {210, 210, 0}, {210, 0, 210}, {210, 112, 0},
70
    {0, 195, 195}, {195, 195, 195}, {0, 0, 195}, {0, 195, 0},
71
    {195, 0, 0}, {195, 195, 0}, {195, 0, 195}, {195, 107, 0},
72
    {0, 195, 195}, {195, 195, 195}, {0, 0, 195}, {0, 195, 0},
73
    {195, 0, 0}, {195, 195, 0}, {195, 0, 195}, {195, 107, 0},
74
    {0, 180, 180}, {180, 180, 180}, {0, 0, 180}, {0, 180, 0},
75
    {180, 0, 0}, {180, 180, 0}, {180, 0, 180}, {180, 102, 0},
76
    {0, 180, 180}, {180, 180, 180}, {0, 0, 180}, {0, 180, 0},
77
    {180, 0, 0}, {180, 180, 0}, {180, 0, 180}, {180, 102, 0},
78
    {0, 165, 165}, {165, 165, 165}, {0, 0, 165}, {0, 165, 0},
79
    {165, 0, 0}, {165, 165, 0}, {165, 0, 165}, {165, 97, 0},
80
    {0, 165, 165}, {165, 165, 165}, {0, 0, 165}, {0, 165, 0},
81
    {165, 0, 0}, {165, 165, 0}, {165, 0, 165}, {165, 97, 0},
82
    {0, 150, 150}, {150, 150, 150}, {0, 0, 150}, {0, 150, 0},
83
    {150, 0, 0}, {150, 150, 0}, {150, 0, 150}, {150, 92, 0},
84
    {0, 150, 150}, {150, 150, 150}, {0, 0, 150}, {0, 150, 0},
85
    {150, 0, 0}, {150, 150, 0}, {150, 0, 150}, {150, 92, 0},
86
    {0, 135, 135}, {135, 135, 135}, {0, 0, 135}, {0, 135, 0},
87
    {135, 0, 0}, {135, 135, 0}, {135, 0, 135}, {135, 87, 0},
88
    {0, 135, 135}, {135, 135, 135}, {0, 0, 135}, {0, 135, 0},
89
    {135, 0, 0}, {135, 135, 0}, {135, 0, 135}, {135, 87, 0},
90
    {0, 120, 120}, {120, 120, 120}, {0, 0, 120}, {0, 120, 0},
91
    {120, 0, 0}, {120, 120, 0}, {120, 0, 120}, {120, 82, 0},
92
    {0, 120, 120}, {120, 120, 120}, {0, 0, 120}, {0, 120, 0},
93
    {120, 0, 0}, {120, 120, 0}, {120, 0, 120}, {120, 82, 0},
94
    {0, 105, 105}, {105, 105, 105}, {0, 0, 105}, {0, 105, 0},
95
    {105, 0, 0}, {105, 105, 0}, {105, 0, 105}, {105, 77, 0},
96
    {0, 105, 105}, {105, 105, 105}, {0, 0, 105}, {0, 105, 0},
97
    {105, 0, 0}, {105, 105, 0}, {105, 0, 105}, {105, 77, 0},
98
    {0, 90, 90}, {90, 90, 90}, {0, 0, 90}, {0, 90, 0},
99
    {90, 0, 0}, {90, 90, 0}, {90, 0, 90}, {90, 72, 0},
100
    {0, 90, 90}, {90, 90, 90}, {0, 0, 90}, {0, 90, 0},
101
    {90, 0, 0}, {90, 90, 0}, {90, 0, 90}, {90, 72, 0},
102
    {0, 75, 75}, {75, 75, 75}, {0, 0, 75}, {0, 75, 0},
103
    {75, 0, 0}, {75, 75, 0}, {75, 0, 75}, {75, 67, 0},
104
    {0, 75, 75}, {75, 75, 75}, {0, 0, 75}, {0, 75, 0},
105
    {75, 0, 0}, {75, 75, 0}, {75, 0, 75}, {75, 67, 0},
106
    {0, 60, 60}, {60, 60, 60}, {0, 0, 60}, {0, 60, 0},
107
    {60, 0, 0}, {60, 60, 0}, {60, 0, 60}, {60, 62, 0},
108
    {0, 60, 60}, {60, 60, 60}, {0, 0, 60}, {0, 60, 0},
109
    {60, 0, 0}, {60, 60, 0}, {60, 0, 60}, {60, 62, 0},
110
    {0, 45, 45}, {45, 45, 45}, {0, 0, 45}, {0, 45, 0},
111
    {45, 0, 0}, {45, 45, 0}, {45, 0, 45}, {45, 57, 0},
112
    {0, 45, 45}, {45, 45, 45}, {0, 0, 45}, {0, 45, 0},
113
    {45, 0, 0}, {45, 45, 0}, {45, 0, 45}, {45, 57, 0},
114
    {0, 30, 30}, {30, 30, 30}, {0, 0, 30}, {0, 30, 0},
115
    {30, 0, 0}, {30, 30, 0}, {30, 0, 30}, {30, 52, 0},
116
    {0, 30, 30}, {30, 30, 30}, {0, 0, 30}, {0, 30, 0},
117
    {30, 0, 0}, {30, 30, 0}, {30, 0, 30}, {192, 192, 192},
118
    {28, 0, 100}};
119
    private int LSB;
120
    private FileInputStream fin;
121

  
122
    // private LEDataInputStream input;
123
    private MappedByteBuffer bb;
124
    private int FALSE = 0;
125
    private int TRUE = 1;
126
    private DGNElemCore elemento;
127
    private DGNInfo info; // Contiene el path y otras cosas
128
    private Rectangle2D.Double m_BoundingBox;
129
    private DGNElemColorTable m_colorTable;
130

  
131
    private boolean logErrors = false;
132
            
133
    public DGNReader(String pathFich) throws DataException {
134
        this(pathFich, false);
135
    }
136
    
137
    public DGNReader(String pathFich, boolean logErrors) throws DataException {
138
        this.logErrors = logErrors;
139
        
140
        info = new DGNInfo();
141

  
142
        DGNElemCore elemento = new DGNElemCore(this);
143
        int iArg;
144
        int bReportExtents = 0;
145
        byte[] achRaw = new byte[64];
146
        achRaw[63] = 1;
147

  
148
        double dfSFXMin = 0.0;
149
        double dfSFXMax = 0.0;
150
        double dfSFYMin = 0.0;
151
        double dfSFYMax = 0.0;
152

  
153
        info.fp = pathFich;
154
        info = DGNOpen(info, 0);
155

  
156
        bb.rewind();
157
        DGNSetSpatialFilter(info, dfSFXMin, dfSFYMin, dfSFXMax, dfSFYMax);
158

  
159
        int nLevel;
160
        int nType;
161
        int[] anLevelTypeCount = new int[128 * 64];
162
        int[] anLevelCount = new int[64];
163
        int[] anTypeCount = new int[128];
164
        double[] adfExtents = new double[6];
165
        int[] nCount = new int[1];
166
        nCount[0] = 0;
167

  
168
        DGNGetExtents(info, adfExtents); // extender
169
        logdebug("X Range:" + adfExtents[0] + ", " + adfExtents[3]);
170
        logdebug("Y Range:" + adfExtents[1] + ", " + adfExtents[4]);
171
        logdebug("Z Range:" + adfExtents[2] + ", " + adfExtents[5]);
172

  
173
        m_BoundingBox = new Rectangle2D.Double();
174
        m_BoundingBox.setRect(adfExtents[0], adfExtents[1],
175
                (adfExtents[3] - adfExtents[0]),
176
                (adfExtents[4] - adfExtents[1]));
177

  
178
        /* m_Renderer = new FRenderer(this); */
179
        DGNElementInfo[] pasEI; // =new DGNElementInfo[nCount+1];
180
        pasEI = DGNGetElementIndex(info, nCount);
181

  
182
        logdebug("Total Elements:" + nCount[0]);
183

  
184
        for (int i = 0; i < nCount[0]; i++) {
185
            anLevelTypeCount[(pasEI[i].level * 128) + pasEI[i].type]++;
186
            anLevelCount[pasEI[i].level]++;
187
            anTypeCount[pasEI[i].type]++;
188
        }
189

  
190
        logdebug("Per Type Report");
191
        logdebug("===============");
192

  
193
        for (nType = 0; nType < 128; nType++) {
194
            if (anTypeCount[nType] != 0) {
195
                logdebug("Type:" + DGNTypeToName(nType) + ":"
196
                        + anTypeCount[nType]);
197
            }
198
        }
199

  
200
        logdebug("Per Level Report\n");
201
        logdebug("================\n");
202
        for (nLevel = 0; nLevel < 64; nLevel++) {
203
            if (anLevelCount[nLevel] == 0) {
204
                continue;
205
            }
206
            logdebug("Level " + nLevel + "," + anLevelCount[nLevel] + "elements:");
207
            for (nType = 0; nType < 128; nType++) {
208
                if (anLevelTypeCount[(nLevel * 128) + nType] != 0) {
209
                    logdebug("  Type " + DGNTypeToName(nType)
210
                            + "," + anLevelTypeCount[(nLevel * 128) + nType]);
211
                }
212
            }
213
        }
214

  
215
        bb.rewind();
216
    }
217

  
218
    public boolean is3D() {
219
        return this.info.dimension==3;
220
    }
221
    
222
    /*
223
     * public Color getColor(int indexColor) { int r,g,b; //
224
     * System.err.println("indexcolor = " + indexColor); // Si no hay tabla de
225
     * colores, interpretamos que todas las cosas son negras if (m_colorTable ==
226
     * null) return new Color(0,0,0);
227
     * 
228
     * r = ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][0]); g =
229
     * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][1]); b =
230
     * ByteUtils.getUnsigned(m_colorTable.color_info[indexColor][2]);
231
     * 
232
     * if ((r==255) && (g==255) & (b==255)) { r=g=b=0; // El color blanco lo
233
     * devolvemos como negro. }
234
     * 
235
     * return new Color(r,g,b); }
236
     */
237
    /**
238
     * Devuelve la informaci?n del DGN.
239
     *
240
     * @return DGNInfo Informaci?n.
241
     */
242
    public DGNInfo getInfo() {
243
        return info;
244
    }
245

  
246
    /**
247
     * Devuelve el n?mero de elementos.
248
     *
249
     * @return N?mero de elementos.
250
     */
251
    public int getNumEntities() {
252
        return info.element_count;
253
    }
254

  
255
    /**
256
     * Devuelve el rect?ngulo del extent.
257
     *
258
     * @return Rect?ngulo.
259
     */
260
    public Rectangle2D getBoundingBox() {
261
        return m_BoundingBox;
262
    }
263

  
264
    /**
265
     * *********************************************************************
266
     */
267
    /* DGNGotoElement() */
268
    /**
269
     * *********************************************************************
270
     */
271
    /**
272
     * Seek to indicated element. Changes what element will be read on the next
273
     * call to DGNReadElement(). Note that this function requires and index, and
274
     * one will be built if not already available.
275
     *
276
     * @param element_id the element to seek to. These values are sequentially
277
     * ordered starting at zero for the first element.
278
     *
279
     * @return returns TRUE on success or FALSE on failure.
280
     */
281
    public int DGNGotoElement(int element_id) {
282
        DGNBuildIndex(info);
283
        if ((element_id < 0) || (element_id >= info.element_count)) {
284
            return FALSE;
285
        }
286
        bb.position((int) info.element_index[element_id].offset);
287

  
288
        info.next_element_id = element_id;
289
        info.in_complex_group = FALSE;
290
        return TRUE;
291
    }
292

  
293
    private DGNInfo DGNOpen(DGNInfo info, int bUpdate) throws DataException {
294
        int pos = 0;
295
        byte[] abyHeader = new byte[512];
296
        info.next_element_id = 0;
297
        info.got_tcb = FALSE;
298
        info.scale = 1.0;
299
        info.origin_x = 0.0;
300
        info.origin_y = 0.0;
301
        info.origin_z = 0.0;
302
        info.index_built = FALSE;
303
        info.element_count = 0;
304
        info.element_index = null;
305
        info.got_bounds = FALSE;
306

  
307
        try {
308
            fin = new FileInputStream(info.fp);
309

  
310
            FileChannel fc = fin.getChannel();
311

  
312
            long sz = fc.size();
313
            int numReg;
314

  
315
            // Get the file's size and then map it into memory
316
            bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
317
            bb.order(ByteOrder.nativeOrder());
318
            bb.get(abyHeader, pos, abyHeader.length);
319

  
320
            info.ftall = (int) (sz / 16);
321

  
322
            if (bb.order() == ByteOrder.LITTLE_ENDIAN) {
323
                LSB = TRUE;
324
            }
325

  
326
            if (DGNTestOpen(abyHeader, abyHeader.length) != FALSE) {
327
                if (abyHeader[0] == (byte) 0xC8) {
328
                    info.dimension = 3; // 0xC8
329
                } else {
330
                    info.dimension = 2;
331
                }
332

  
333
                info.has_spatial_filter = FALSE;
334
                info.sf_converted_to_uor = FALSE;
335
                info.select_complex_group = FALSE;
336
                info.in_complex_group = FALSE;
337
            }
338
        } catch (FileNotFoundException e) {
339
            throw new org.gvsig.fmap.dal.exception.FileNotFoundException(
340
                    info.fp);
341
        } catch (Exception e) {
342
            throw new ReadException("DGNReader error", e);
343
        }
344

  
345
        return info;
346
    }
347

  
348
    /**
349
     * Comprobaci?n si se puede abrir el fichero.
350
     *
351
     * @param pabyHeader Vector byte con el header.
352
     * @param nByteCount n?mero de bytes.
353
     *
354
     * @return Devuelve un enteor que muestra si no hay errores.
355
     */
356
    private int DGNTestOpen(byte[] pabyHeader, int nByteCount) {
357
        if (nByteCount < 4) {
358
            return TRUE;
359
        }
360

  
361
        // Is it a cell library?
362
        if ((pabyHeader[0] == (byte) 0x08) && (pabyHeader[1] == (byte) 0x05)
363
                && (pabyHeader[2] == (byte) 0x17)
364
                && (pabyHeader[3] == (byte) 0x00)) {
365
            return TRUE;
366
        }
367

  
368
        // Is it not a regular 2D or 3D file?
369
        if (((pabyHeader[0] != (byte) 0x08) && (pabyHeader[0] != (byte) 0xC8))
370
                || (pabyHeader[1] != (byte) 0x09)
371
                || (pabyHeader[2] != (byte) 0xFE)
372
                || (pabyHeader[3] != (byte) 0x02)) {
373
            return FALSE;
374
        }
375

  
376
        return TRUE;
377
    }
378

  
379
    /**
380
     * Lee una fila del elemento.
381
     *
382
     * @param info Informaci?n del DGN.
383
     * @param core Elemento.
384
     *
385
     * @return Devuelve un entero que muestra si se ha calculado correctamente.
386
     */
387
    private int DGNLoadRawElement(DGNInfo info, DGNElemCore core) {
388
        /* -------------------------------------------------------------------- */
389
        /* Read the first four bytes to get the level, type, and word */
390
        /* count. */
391
        /* -------------------------------------------------------------------- */
392

  
393
        // int nType, nWords, nLevel;
394
        int nType = 0;
395
        int nWords = 0;
396
        int nLevel = 0;
397
        int bytesCount = 0;
398

  
399
        try {
400
            // input=new LEDataInputStream(fin);
401
            for (int i = 0; i < 4; i++) {
402
                info.abyElem[i] = bb.get();
403
                if (i == 1) {
404
                    if ((info.abyElem[0] == -1) && (info.abyElem[1] == -1)) {
405
                        return FALSE;
406
                    }
407
                }
408

  
409
                // info.temporal[i]=input.readByte();
410
            }
411

  
412
            nWords = ByteUtils.byteToUnsignedInt(info.abyElem[2])
413
                    + (ByteUtils.byteToUnsignedInt(info.abyElem[3]) * 256);
414
            nType = ByteUtils.byteToUnsignedInt(info.abyElem[1]) & 0x7f;
415
            nLevel = ByteUtils.byteToUnsignedInt(info.abyElem[0]) & 0x3f;
416

  
417
            /*
418
             * ------------------------------------------------------------------
419
             */
420
            /* Read the rest of the element data into the working buffer. */
421
            if (((nWords * 2) + 4) > info.abyElem.length) {
422
                return FALSE;
423
            }
424
            for (; bytesCount < (nWords * 2) && bb.hasRemaining(); bytesCount++) {
425
                info.abyElem[bytesCount + 4] = bb.get();
426
            }
427
            info.ftall = bb.position();
428
        } catch (Exception e) {
429
            logwarn(MessageFormat.format("The DGN file {0} may not be loaded correctly.\n"
430
                    + "Error loading:\n"
431
                    + "nWords = {1}\n"
432
                    + "info.next_element_id {2}\n"
433
                    + "info.abyElem.length =  {3}\n"
434
                    + "bb.position() =  {4}",
435
                    info.fp,
436
                    nWords,
437
                    info.next_element_id,
438
                    info.abyElem.length,
439
                    bb.position()), e);
440

  
441
            return FALSE;
442
        }
443

  
444
        info.nElemBytes = bytesCount + 4;
445
        info.next_element_id++;
446

  
447
        /* -------------------------------------------------------------------- */
448
        /* Return requested info. */
449
        /* -------------------------------------------------------------------- */
450
        core.type = nType;
451

  
452
        core.level = nLevel;
453

  
454
        return TRUE;
455
    }
456

  
457
    /**
458
     * Calcula el filtro espacial al rect?ngulo del elemento.
459
     *
460
     * @param info Informaci?n del DGN.
461
     */
462
    private void DGNSpatialFilterToUOR(DGNInfo info) {
463
        DGNPoint sMin = new DGNPoint();
464
        DGNPoint sMax = new DGNPoint();
465

  
466
        if ((info.sf_converted_to_uor == 1)
467
                || (!(info.has_spatial_filter == 1)) || (!(info.got_tcb == 1))) {
468
            return;
469
        }
470

  
471
        sMin.x = info.sf_min_x_geo;
472
        sMin.y = info.sf_min_y_geo;
473
        sMin.z = 0;
474

  
475
        sMax.x = info.sf_max_x_geo;
476
        sMax.y = info.sf_max_y_geo;
477
        sMax.z = 0;
478

  
479
        DGNInverseTransformPoint(info, sMin);
480
        DGNInverseTransformPoint(info, sMax);
481

  
482
        info.sf_min_x = (long) (sMin.x + 2147483648.0);
483
        info.sf_min_y = (long) (sMin.y + 2147483648.0);
484
        info.sf_max_x = (long) (sMax.x + 2147483648.0);
485
        info.sf_max_y = (long) (sMax.y + 2147483648.0);
486

  
487
        info.sf_converted_to_uor = TRUE;
488
    }
489

  
490
    /**
491
     * Calcula un punto aplicandole la transformaci?n.
492
     *
493
     * @param info Informaci?n del DGN.
494
     * @param punto Punto.
495
     */
496
    private void DGNInverseTransformPoint(DGNInfo info, DGNPoint punto) {
497
        punto.x = (punto.x + info.origin_x) / info.scale;
498
        punto.y = (punto.y + info.origin_y) / info.scale;
499
        punto.z = (punto.z + info.origin_z) / info.scale;
500

  
501
        punto.x = Math.max(-2147483647, Math.min(2147483647, punto.x));
502
        punto.y = Math.max(-2147483647, Math.min(2147483647, punto.y));
503
        punto.z = Math.max(-2147483647, Math.min(2147483647, punto.z));
504
    }
505

  
506
    public DGNElemCore DGNReadElement() {
507
        DGNElemCore elemento = new DGNElemCore(this);
508
        int nType;
509
        int nLevel;
510
        int bInsideFilter;
511

  
512
        /* -------------------------------------------------------------------- */
513
        /* Load the element data into the current buffer. If a spatial */
514
        /* filter is in effect, loop until we get something within our */
515
        /* spatial constraints. */
516
        /* -------------------------------------------------------------------- */
517
        do {
518
            bInsideFilter = TRUE;
519

  
520
            int fin_fichero = DGNLoadRawElement(info, elemento);
521

  
522
            if (fin_fichero == FALSE) {
523
                return null;
524
            }
525

  
526
            if (info.has_spatial_filter != FALSE) {
527
                if (info.sf_converted_to_uor == FALSE) {
528
                    DGNSpatialFilterToUOR(info);
529
                }
530

  
531
                if (DGNGetRawExtents(info, null, elemento) == null) {
532
                    bInsideFilter = TRUE;
533
                } else if ((info.min_x > info.sf_max_x)
534
                        || (info.min_y > info.sf_max_y)
535
                        || (info.max_x < info.sf_min_x)
536
                        || (info.max_y < info.sf_min_y)) {
537
                    bInsideFilter = FALSE;
538
                }
539

  
540
                if ((elemento.type == DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER)
541
                        || (elemento.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER)) {
542
                    info.in_complex_group = TRUE;
543
                    info.select_complex_group = bInsideFilter;
544
                } else if ((info.abyElem[0] & (byte) 0x80) != FALSE) {
545
                    if (info.in_complex_group == TRUE) {
546
                        bInsideFilter = info.select_complex_group;
547
                    }
548
                } else {
549
                    info.in_complex_group = FALSE;
550
                }
551
            }
552
        } while (bInsideFilter == FALSE);
553

  
554
        elemento = DGNProcessElement(info, elemento.type, elemento.level);
555

  
556
        return elemento;
557
    }
558

  
559
    /**
560
     * Devuelve los extent de una fila.
561
     *
562
     * @param info Informaci?n del DGN.
563
     * @param pabyRawData Vector de byte.
564
     * @param elemento Elemento.
565
     *
566
     * @return Vector de double.
567
     */
568
    public double[] DGNGetRawExtents(DGNInfo info, byte[] pabyRawData,
569
            DGNElemCore elemento) {
570
        if (pabyRawData == null) {
571
            pabyRawData = info.abyElem;
572
        }
573

  
574
        double[] tempo = new double[6];
575

  
576
        switch (elemento.type) {
577
            case DGNFileHeader.DGNT_LINE:
578
            case DGNFileHeader.DGNT_LINE_STRING:
579
            case DGNFileHeader.DGNT_SHAPE:
580
            case DGNFileHeader.DGNT_CURVE:
581
            case DGNFileHeader.DGNT_BSPLINE:
582
            case DGNFileHeader.DGNT_ELLIPSE:
583
            case DGNFileHeader.DGNT_ARC:
584
            case DGNFileHeader.DGNT_TEXT:
585
            case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
586
            case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER:
587

  
588
                byte[] temp = new byte[4];
589
                System.arraycopy(pabyRawData, 4, temp, 0, 4);
590
                tempo[0] = DGN_INT32(temp); // 4
591

  
592
                System.arraycopy(pabyRawData, 8, temp, 0, 4);
593
                tempo[1] = DGN_INT32(temp);
594

  
595
                System.arraycopy(pabyRawData, 12, temp, 0, 4);
596
                tempo[2] = DGN_INT32(temp);
597

  
598
                System.arraycopy(pabyRawData, 16, temp, 0, 4);
599
                tempo[3] = DGN_INT32(temp);
600

  
601
                System.arraycopy(pabyRawData, 20, temp, 0, 4);
602
                tempo[4] = DGN_INT32(temp);
603

  
604
                System.arraycopy(pabyRawData, 24, temp, 0, 4);
605
                tempo[5] = DGN_INT32(temp);
606

  
607
                return tempo;
608

  
609
            default:
610
                return null;
611
        }
612
    }
613

  
614
    /**
615
     * A partir de un vector de byte devuelve un double.
616
     *
617
     * @param p Vector de byte.
618
     *
619
     * @return double.
620
     */
621
    private double DGN_INT32(byte[] p) {
622
        int x = 256;
623
        int x0;
624
        int x1;
625
        int x2;
626
        int x3;
627
        x0 = p[0];
628
        x1 = p[1];
629
        x2 = p[2];
630
        x3 = p[3];
631

  
632
        if (p[0] < 0) {
633
            x0 = x + p[0];
634
        }
635

  
636
        if (p[1] < 0) {
637
            x1 = x + p[1];
638
        }
639

  
640
        if (p[2] < 0) {
641
            x2 = x + p[2];
642
        }
643

  
644
        if (p[3] < 0) {
645
            x3 = x + p[3];
646
        }
647

  
648
        return (x2 + (x3 * 256) + (x1 * 65536 * 256) + (x0 * 65536));
649
    }
650

  
651
    private DGNElemCore DGNProcessElement(DGNInfo info, int nType, int nLevel) {
652
        DGNElemCore elemento = new DGNElemCore(this);
653

  
654
        switch (nType) {
655
            case DGNFileHeader.DGNT_SHARED_CELL_DEFN:
656
                logdebug("DGNProcessElement (DGNT_SHARED_CELL_DEFN): Type " + DGNTypeToName(nType));
657
                elemento.stype = DGNFileHeader.DGNST_SHARED_CELL_DEFN;
658
                DGNParseCore(info, elemento);
659

  
660
                break;
661

  
662
            case DGNFileHeader.DGNT_CELL_HEADER: {
663
                DGNElemCellHeader psCell = new DGNElemCellHeader(this);
664
                psCell.stype = DGNFileHeader.DGNST_CELL_HEADER;
665
                DGNParseCore(info, psCell);
666
                psCell.totlength = ByteUtils.getUnsigned(info.abyElem[36])
667
                        + (ByteUtils.getUnsigned(info.abyElem[37]) * 256);
668

  
669
                byte[] temp = new byte[psCell.name.length];
670
                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
671
                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[38])
672
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256),
673
                        temp);
674

  
675
                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length - 3);
676

  
677
                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[40])
678
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256),
679
                        temp);
680
                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
681
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
682
                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
683
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
684
                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
685
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
686
                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
687
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
688
                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
689
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
690
                psCell.color = info.abyElem[35];
691

  
692
                if (info.dimension == 2) {
693
                    byte[] temp1 = new byte[4];
694
                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
695
                    psCell.rnglow.x = DGN_INT32(temp1);
696
                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
697
                    psCell.rnglow.y = DGN_INT32(temp);
698
                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
699
                    psCell.rnghigh.x = DGN_INT32(temp1);
700
                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
701
                    psCell.rnghigh.y = DGN_INT32(temp1);
702
                    System.arraycopy(info.abyElem, 84, temp1, 0, 4);
703
                    psCell.origin.x = DGN_INT32(temp1);
704
                    System.arraycopy(info.abyElem, 88, temp1, 0, 4);
705
                    psCell.origin.y = DGN_INT32(temp1);
706

  
707
                    {
708
                        double a;
709
                        double b;
710
                        double c;
711
                        double d;
712
                        double a2;
713
                        double c2;
714
                        System.arraycopy(info.abyElem, 68, temp1, 0, 4);
715
                        a = DGN_INT32(temp1);
716
                        System.arraycopy(info.abyElem, 72, temp1, 0, 4);
717
                        b = DGN_INT32(temp1);
718
                        System.arraycopy(info.abyElem, 76, temp1, 0, 4);
719
                        c = DGN_INT32(temp1);
720
                        System.arraycopy(info.abyElem, 80, temp1, 0, 4);
721
                        d = DGN_INT32(temp1);
722
                        a2 = a * a;
723
                        c2 = c * c;
724
                        psCell.xscale = Math.sqrt(a2 + c2) / 214748;
725
                        psCell.yscale = Math.sqrt((b * b) + (d * d)) / 214748;
726
                        psCell.rotation = Math.acos(a / Math.sqrt(a2 + c2));
727

  
728
                        if (b <= 0) {
729
                            psCell.rotation = (psCell.rotation * 180) / Math.PI;
730
                        } else {
731
                            psCell.rotation = 360 - ((psCell.rotation * 180) / Math.PI);
732
                        }
733
                    }
734
                } else {
735
                    byte[] temp1 = new byte[4];
736
                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
737
                    psCell.rnglow.x = DGN_INT32(temp1);
738
                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
739
                    psCell.rnglow.y = DGN_INT32(temp1);
740
                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
741
                    psCell.rnglow.z = DGN_INT32(temp1);
742
                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
743
                    psCell.rnghigh.x = DGN_INT32(temp1);
744
                    System.arraycopy(info.abyElem, 68, temp1, 0, 4);
745
                    psCell.rnghigh.y = DGN_INT32(temp1);
746
                    System.arraycopy(info.abyElem, 72, temp1, 0, 4);
747
                    psCell.rnghigh.z = DGN_INT32(temp1);
748

  
749
                    System.arraycopy(info.abyElem, 112, temp1, 0, 4);
750
                    psCell.origin.x = DGN_INT32(temp1);
751
                    System.arraycopy(info.abyElem, 116, temp1, 0, 4);
752
                    psCell.origin.y = DGN_INT32(temp1);
753
                    System.arraycopy(info.abyElem, 120, temp1, 0, 4);
754
                    psCell.origin.z = DGN_INT32(temp1);
755
                }
756

  
757
                DGNTransformPoint(info, psCell.rnglow);
758
                DGNTransformPoint(info, psCell.rnghigh);
759
                DGNTransformPoint(info, psCell.origin);
760
                elemento = psCell;
761
            }
762

  
763
            break;
764

  
765
            case DGNFileHeader.DGNT_CELL_LIBRARY: {
766
                logdebug("DGNProcessElement (DGNT_CELL_LIBRARY): Type " + DGNTypeToName(nType));
767

  
768
                DGNElemCellLibrary psCell = new DGNElemCellLibrary(this);
769
                int iWord;
770
                psCell.stype = DGNFileHeader.DGNST_CELL_LIBRARY;
771
                DGNParseCore(info, psCell);
772

  
773
                byte[] temp = new byte[psCell.name.length];
774
                System.arraycopy(psCell.name, 0, temp, 0, psCell.name.length);
775
                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[32])
776
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[33]) * 256),
777
                        temp);
778
                System.arraycopy(psCell.name, 3, temp, 0, psCell.name.length);
779
                DGNRad50ToAscii(ByteUtils.byteToUnsignedInt(info.abyElem[34])
780
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[35]) * 256),
781
                        temp);
782
                psCell.properties = info.abyElem[38] + (info.abyElem[39] * 256);
783
                psCell.dispsymb = ByteUtils.byteToUnsignedInt(info.abyElem[40])
784
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[41]) * 256);
785
                psCell.cclass = ByteUtils.byteToUnsignedInt(info.abyElem[42])
786
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[43]) * 256);
787
                psCell.levels[0] = ByteUtils.byteToUnsignedInt(info.abyElem[44])
788
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[45]) * 256);
789
                psCell.levels[1] = ByteUtils.byteToUnsignedInt(info.abyElem[46])
790
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[47]) * 256);
791
                psCell.levels[2] = ByteUtils.byteToUnsignedInt(info.abyElem[48])
792
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[49]) * 256);
793
                psCell.levels[3] = ByteUtils.byteToUnsignedInt(info.abyElem[50])
794
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[51]) * 256);
795
                psCell.numwords = ByteUtils.byteToUnsignedInt(info.abyElem[36])
796
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
797

  
798
                for (iWord = 0; iWord < 9; iWord++) {
799
                    int iOffset = 52 + (iWord * 2);
800
                    System.arraycopy(psCell.name, iWord * 3, temp, 0,
801
                            psCell.description.length);
802
                    DGNRad50ToAscii(
803
                            ByteUtils.byteToUnsignedInt(info.abyElem[iOffset])
804
                            + (ByteUtils
805
                            .byteToUnsignedInt(info.abyElem[iOffset + 1]) * 256),
806
                            temp);
807
                }
808

  
809
                elemento = psCell;
810
            }
811

  
812
            break;
813

  
814
            case DGNFileHeader.DGNT_LINE: {
815
                DGNElemMultiPoint psLine = new DGNElemMultiPoint(this);
816
                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
817
                DGNParseCore(info, psLine);
818
                psLine.num_vertices = 2;
819
                psLine.vertices = new DGNPoint[psLine.num_vertices];
820

  
821
                if (info.dimension == 2) {
822
                    byte[] temp1 = new byte[4];
823
                    System.arraycopy(info.abyElem, 36, temp1, 0, 4);
824
                    psLine.vertices[0] = new DGNPoint();
825
                    psLine.vertices[0].x = DGN_INT32(temp1);
826
                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
827
                    psLine.vertices[0].y = DGN_INT32(temp1);
828
                    System.arraycopy(info.abyElem, 44, temp1, 0, 4);
829
                    psLine.vertices[1] = new DGNPoint();
830
                    psLine.vertices[1].x = DGN_INT32(temp1);
831
                    System.arraycopy(info.abyElem, 48, temp1, 0, 4);
832
                    psLine.vertices[1].y = DGN_INT32(temp1);
833
                } else {
834
                    byte[] temp1 = new byte[4];
835
                    System.arraycopy(info.abyElem, 36, temp1, 0, 4);
836
                    psLine.vertices[0] = new DGNPoint();
837
                    psLine.vertices[0].x = DGN_INT32(temp1);
838
                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
839
                    psLine.vertices[0].y = DGN_INT32(temp1);
840
                    System.arraycopy(info.abyElem, 44, temp1, 0, 4);
841
                    psLine.vertices[0].z = DGN_INT32(temp1);
842
                    System.arraycopy(info.abyElem, 48, temp1, 0, 4);
843
                    psLine.vertices[1] = new DGNPoint();
844
                    psLine.vertices[1].x = DGN_INT32(temp1);
845
                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
846
                    psLine.vertices[1].y = DGN_INT32(temp1);
847
                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
848
                    psLine.vertices[1].z = DGN_INT32(temp1);
849
                }
850

  
851
                DGNTransformPoint(info, psLine.vertices[0]);
852
                DGNTransformPoint(info, psLine.vertices[1]);
853
                elemento = psLine;
854
            }
855

  
856
            break;
857

  
858
            case DGNFileHeader.DGNT_LINE_STRING:
859
            case DGNFileHeader.DGNT_SHAPE: // regular
860
            case DGNFileHeader.DGNT_CURVE: // mal
861
            case DGNFileHeader.DGNT_BSPLINE: // aceptable
862
            {
863
                DGNElemMultiPoint psLine = new DGNElemMultiPoint(this);
864
                int i;
865
                int count;
866
                int pntsize = info.dimension * 4;
867

  
868
                count = ByteUtils.byteToUnsignedInt(info.abyElem[36])
869
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
870
                psLine.stype = DGNFileHeader.DGNST_MULTIPOINT;
871
                DGNParseCore(info, psLine);
872

  
873
                if (info.nElemBytes < (38 + (count * pntsize))) {
874
                    logdebug("Error en los vertices de multipunto");
875
                    count = (info.nElemBytes - 38) / pntsize;
876
                    return null;
877
                }
878

  
879
                psLine.num_vertices = count;
880
                psLine.vertices = new DGNPoint[psLine.num_vertices];
881

  
882
                for (i = 0; i < psLine.num_vertices; i++) {
883
                    byte[] temp1 = new byte[4];
884
                    System.arraycopy(info.abyElem, 38 + (i * pntsize), temp1, 0, 4);
885
                    psLine.vertices[i] = new DGNPoint();
886
                    psLine.vertices[i].x = DGN_INT32(temp1);
887
                    System.arraycopy(info.abyElem, 42 + (i * pntsize), temp1, 0, 4);
888
                    psLine.vertices[i].y = DGN_INT32(temp1);
889

  
890
                    if (info.dimension == 3) {
891
                        System.arraycopy(info.abyElem, 46 + (i * pntsize), temp1,
892
                                0, 4);
893
                        psLine.vertices[i].z = DGN_INT32(temp1);
894
                    }
895

  
896
                    DGNTransformPoint(info, psLine.vertices[i]);
897
                }
898

  
899
                elemento = psLine;
900
            }
901

  
902
            break;
903

  
904
            case DGNFileHeader.DGNT_GROUP_DATA:
905
                if (nLevel == DGNFileHeader.DGN_GDL_COLOR_TABLE) {
906
                    elemento = DGNParseColorTable(info);
907
                } else {
908
                    elemento.stype = DGNFileHeader.DGNST_CORE;
909
                    DGNParseCore(info, elemento);
910
                }
911
                break;
912

  
913
            case DGNFileHeader.DGNT_ELLIPSE: {
914
                DGNElemArc psEllipse = new DGNElemArc(this);
915

  
916
                psEllipse.stype = DGNFileHeader.DGNST_ARC;
917
                DGNParseCore(info, psEllipse);
918

  
919
                int[] fin = new int[1];
920
                fin[0] = 0;
921

  
922
                byte[] temp1 = new byte[8];
923
                System.arraycopy(info.abyElem, 36, temp1, 0, 8);
924

  
925
                fin[0] = 0;
926
                psEllipse.primary_axis = DGNParseIEEE(temp1);
927

  
928
                psEllipse.primary_axis *= info.scale;
929
                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
930
                fin[0] = 0;
931

  
932
                psEllipse.secondary_axis = DGNParseIEEE(temp1);
933
                psEllipse.secondary_axis *= info.scale;
934

  
935
                if (info.dimension == 2) {
936
                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
937
                    psEllipse.rotation = DGN_INT32(temp1);
938
                    psEllipse.rotation = psEllipse.rotation / 360000.0;
939
                    System.arraycopy(info.abyElem, 56, temp1, 0, 8);
940
                    fin[0] = 0;
941

  
942
                    psEllipse.origin.x = DGNParseIEEE(temp1);
943
                    System.arraycopy(info.abyElem, 64, temp1, 0, 8);
944
                    fin[0] = 0;
945

  
946
                    psEllipse.origin.y = DGNParseIEEE(temp1);
947
                } else {
948
                    // leave quaternion for later
949
                    System.arraycopy(info.abyElem, 68, temp1, 0, 8);
950
                    fin[0] = 0;
951
                    psEllipse.origin.x = DGNParseIEEE(temp1);
952

  
953
                    System.arraycopy(info.abyElem, 76, temp1, 0, 8);
954
                    fin[0] = 0;
955
                    psEllipse.origin.y = DGNParseIEEE(temp1);
956

  
957
                    System.arraycopy(info.abyElem, 84, temp1, 0, 8);
958
                    fin[0] = 0;
959
                    psEllipse.origin.z = DGNParseIEEE(temp1);
960

  
961
                    System.arraycopy(info.abyElem, 52, temp1, 0, 4);
962
                    psEllipse.quat[0] = DGN_INT32(temp1);
963
                    System.arraycopy(info.abyElem, 56, temp1, 0, 4);
964
                    psEllipse.quat[1] = DGN_INT32(temp1);
965
                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
966
                    psEllipse.quat[2] = DGN_INT32(temp1);
967
                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
968
                    psEllipse.quat[3] = DGN_INT32(temp1);
969
                }
970

  
971
                DGNTransformPoint(info, (psEllipse.origin));
972

  
973
                psEllipse.startang = 0.0;
974
                psEllipse.sweepang = 360.0;
975
                elemento = psEllipse;
976
            }
977

  
978
            break;
979

  
980
            case DGNFileHeader.DGNT_ARC: {
981
                DGNElemArc psEllipse = new DGNElemArc(this);
982
                double nSweepVal;
983

  
984
                psEllipse.stype = DGNFileHeader.DGNST_ARC;
985
                DGNParseCore(info, psEllipse);
986

  
987
                int[] fin = new int[1];
988
                fin[0] = 0;
989

  
990
                byte[] temp1 = new byte[8];
991
                System.arraycopy(info.abyElem, 36, temp1, 0, 4);
992
                psEllipse.startang = DGN_INT32(temp1);
993
                psEllipse.startang = psEllipse.startang / 360000.0;
994

  
995
                if ((info.abyElem[41] & (byte) 0x80) != FALSE) {
996
                    info.abyElem[41] &= (byte) 0x7f;
997
                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
998
                    nSweepVal = -1 * DGN_INT32(temp1);
999
                } else {
1000
                    System.arraycopy(info.abyElem, 40, temp1, 0, 4);
1001
                    nSweepVal = DGN_INT32(temp1);
1002
                }
1003

  
1004
                if (nSweepVal == 0) {
1005
                    psEllipse.sweepang = 360.0;
1006
                } else {
1007
                    psEllipse.sweepang = nSweepVal / 360000.0;
1008
                }
1009

  
1010
                System.arraycopy(info.abyElem, 44, temp1, 0, 8);
1011
                fin[0] = 0;
1012
                psEllipse.primary_axis = DGNParseIEEE(temp1);
1013

  
1014
                psEllipse.primary_axis *= info.scale;
1015
                System.arraycopy(info.abyElem, 52, temp1, 0, 8);
1016
                fin[0] = 0;
1017
                psEllipse.secondary_axis = DGNParseIEEE(temp1);
1018

  
1019
                psEllipse.secondary_axis *= info.scale;
1020

  
1021
                if (info.dimension == 2) {
1022
                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1023
                    psEllipse.rotation = DGN_INT32(temp1);
1024
                    psEllipse.rotation = psEllipse.rotation / 360000.0;
1025
                    System.arraycopy(info.abyElem, 64, temp1, 0, 8);
1026
                    fin[0] = 0;
1027
                    psEllipse.origin.x = DGNParseIEEE(temp1);
1028

  
1029
                    System.arraycopy(info.abyElem, 72, temp1, 0, 8);
1030
                    fin[0] = 0;
1031
                    psEllipse.origin.y = DGNParseIEEE(temp1);
1032
                } else {
1033
                    // for now we don't try to handle quaternion
1034
                    psEllipse.rotation = 0;
1035
                    System.arraycopy(info.abyElem, 76, temp1, 0, 8);
1036
                    fin[0] = 0;
1037

  
1038
                    psEllipse.origin.x = DGNParseIEEE(temp1);
1039
                    System.arraycopy(info.abyElem, 84, temp1, 0, 8);
1040
                    fin[0] = 0;
1041

  
1042
                    psEllipse.origin.y = DGNParseIEEE(temp1);
1043
                    System.arraycopy(info.abyElem, 92, temp1, 0, 8);
1044
                    fin[0] = 0;
1045

  
1046
                    psEllipse.origin.z = DGNParseIEEE(temp1);
1047
                    System.arraycopy(info.abyElem, 60, temp1, 0, 4);
1048
                    psEllipse.quat[0] = DGN_INT32(temp1);
1049
                    System.arraycopy(info.abyElem, 64, temp1, 0, 4);
1050
                    psEllipse.quat[1] = DGN_INT32(temp1);
1051
                    System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1052
                    psEllipse.quat[2] = DGN_INT32(temp1);
1053
                    System.arraycopy(info.abyElem, 72, temp1, 0, 4);
1054
                    psEllipse.quat[3] = DGN_INT32(temp1);
1055
                }
1056

  
1057
                DGNTransformPoint(info, (psEllipse.origin));
1058
                elemento = psEllipse;
1059
            }
1060

  
1061
            break;
1062

  
1063
            case DGNFileHeader.DGNT_TEXT: {
1064
                DGNElemText psText = new DGNElemText(this);
1065
                int num_chars;
1066
                int text_off;
1067

  
1068
                if (info.dimension == 2) {
1069
                    num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[58]);
1070
                } else {
1071
                    num_chars = ByteUtils.byteToUnsignedInt(info.abyElem[74]);
1072
                }
1073

  
1074
                psText.stype = DGNFileHeader.DGNST_TEXT;
1075
                DGNParseCore(info, psText);
1076

  
1077
                psText.font_id = ByteUtils.byteToUnsignedInt(info.abyElem[36]);
1078
                psText.justification = ByteUtils
1079
                        .byteToUnsignedInt(info.abyElem[37]);
1080

  
1081
                byte[] temp1 = new byte[8];
1082
                System.arraycopy(info.abyElem, 38, temp1, 0, 4);
1083
                psText.length_mult = (DGN_INT32(temp1) * info.scale * 6.0) / 1000.0;
1084
                System.arraycopy(info.abyElem, 42, temp1, 0, 4);
1085
                psText.height_raw = DGN_INT32(temp1) ;
1086
                psText.height_mult = (psText.height_raw * info.scale * 6.0) / 1000.0;
1087

  
1088
                int[] fin = new int[1];
1089
                fin[0] = 0;
1090

  
1091
                if (info.dimension == 2) {
1092
                    System.arraycopy(info.abyElem, 46, temp1, 0, 4);
1093
                    psText.rotation = DGN_INT32(temp1);
1094
                    psText.rotation = psText.rotation / 360000.0;
1095
                    System.arraycopy(info.abyElem, 50, temp1, 0, 4);
1096
                    psText.origin.x = DGN_INT32(temp1);
1097
                    System.arraycopy(info.abyElem, 54, temp1, 0, 4);
1098
                    psText.origin.y = DGN_INT32(temp1);
1099
                    text_off = 60;
1100
                } else {
1101
                    /* leave quaternion for later */
1102
                    System.arraycopy(info.abyElem, 62, temp1, 0, 4);
1103
                    psText.origin.x = DGN_INT32(temp1);
1104
                    System.arraycopy(info.abyElem, 66, temp1, 0, 4);
1105
                    psText.origin.y = DGN_INT32(temp1);
1106
                    System.arraycopy(info.abyElem, 70, temp1, 0, 4);
1107
                    psText.origin.z = DGN_INT32(temp1);
1108
                    text_off = 76;
1109
                }
1110

  
1111
                DGNTransformPoint(info, (psText.origin));
1112

  
1113
                // TODO: AQUI FALTA METER ALGO PARA SOPORTAR TEXTOS MULTYBYTE
1114
                byte[] temp = new byte[num_chars];
1115
                System.arraycopy(info.abyElem, text_off, temp, 0, num_chars);
1116

  
1117
                String strAux = null;
1118

  
1119
                try {
1120
                    psText.string = new String(temp, "ISO-8859-1");
1121
                } catch (Exception e) {
1122
                    logwarn("Can't create java string from byte array (" + dumpBuffer(temp) + ").", e);
1123
                }
1124

  
1125
                elemento = psText;
1126
            }
1127

  
1128
            break;
1129

  
1130
            case DGNFileHeader.DGNT_TCB:
1131
                if (info.got_tcb == FALSE) {
1132
                    elemento = DGNParseTCB(info);
1133
                    elemento.level = nLevel;
1134
                    elemento.type = nType;
1135
                }
1136
                break;
1137

  
1138
            case DGNFileHeader.DGNT_COMPLEX_CHAIN_HEADER:
1139
            case DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER: {
1140
                DGNElemComplexHeader psHdr = new DGNElemComplexHeader(this);
1141

  
1142
                psHdr.stype = DGNFileHeader.DGNST_COMPLEX_HEADER;
1143
                DGNParseCore(info, psHdr);
1144

  
1145
                psHdr.totlength = ByteUtils.byteToUnsignedInt(info.abyElem[36])
1146
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[37]) * 256);
1147
                psHdr.numelems = ByteUtils.byteToUnsignedInt(info.abyElem[38])
1148
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[39]) * 256);
1149
                elemento = psHdr;
1150
            }
1151

  
1152
            break;
1153

  
1154
            case DGNFileHeader.DGNT_TAG_VALUE: {
1155
                DGNElemTagValue psTag = new DGNElemTagValue(this);
1156

  
1157
                psTag.stype = DGNFileHeader.DGNST_TAG_VALUE;
1158
                DGNParseCore(info, psTag);
1159

  
1160
                int[] fin = new int[1];
1161
                fin[0] = 0;
1162

  
1163
                byte[] temp1 = new byte[8];
1164
                psTag.tagType = ByteUtils.byteToUnsignedInt(info.abyElem[74])
1165
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[75]) * 256);
1166
                System.arraycopy(info.abyElem, 68, temp1, 0, 4);
1167
                fin[0] = 0;
1168
                psTag.tagSet = ByteUtils.bytesToInt(temp1, fin);
1169

  
1170
                psTag.tagSet = CPL_LSBWORD32(psTag.tagSet);
1171
                psTag.tagIndex = ByteUtils.byteToUnsignedInt(info.abyElem[72])
1172
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[73]) * 256);
1173
                psTag.tagLength = ByteUtils.byteToUnsignedInt(info.abyElem[150])
1174
                        + (ByteUtils.byteToUnsignedInt(info.abyElem[151]) * 256);
1175

  
1176
                if (psTag.tagType == 1) {
1177
                    byte[] temp = new byte[info.abyElem.length - 154];
1178
                    System.arraycopy(info.abyElem, 4, temp1, 0, // 154
1179
                            4); // info.abyElem.length - 154
1180
                    fin[0] = 0;
1181
                    psTag.tagValue.string = ByteUtils.bytesToString(temp1, fin).toCharArray();
1182
                } else if (psTag.tagType == 3) {
1183
                    byte[] temp = new byte[4];
1184
                    System.arraycopy(info.abyElem, 154, temp1, 0, 4);
1185
                    fin[0] = 0;
1186
                    psTag.tagValue.integer = ByteUtils.bytesToInt(temp1, fin);
1187

  
1188
                    psTag.tagValue.integer = CPL_LSBWORD32((int) psTag.tagValue.integer);
1189
                } else if (psTag.tagType == 4) {
1190
                    byte[] temp = new byte[8];
1191
                    System.arraycopy(info.abyElem, 154, temp1, 0, 8);
1192
                    fin[0] = 0;
1193
                    psTag.tagValue.real = DGNParseIEEE(temp1);
1194
                }
1195

  
1196
                elemento = psTag;
1197
            }
1198

  
1199
            break;
1200

  
1201
            default: {
1202
                elemento.stype = DGNFileHeader.DGNST_CORE;
1203
                DGNParseCore(info, elemento);
1204
            }
1205

  
1206
            break;
1207
        }
1208

  
1209
        /* -------------------------------------------------------------------- */
1210
        /* If the element structure type is "core" or if we are running */
1211
        /* in "capture all" mode, record the complete binary image of */
1212
        /* the element. */
1213
        /* -------------------------------------------------------------------- */
1214
        if ((elemento.stype == DGNFileHeader.DGNST_CORE)
1215
                || ((info.options & DGNFileHeader.DGNO_CAPTURE_RAW_DATA) != FALSE)) {
1216
            elemento.raw_bytes = info.nElemBytes;
1217

  
1218
            elemento.raw_data = new byte[elemento.raw_bytes];
1219

  
1220
            int[] fin = new int[1];
1221
            fin[0] = 0;
1222
            System.arraycopy(info.abyElem, 0, elemento.raw_data, 0,
1223
                    elemento.raw_bytes);
1224
        }
1225

  
1226
        /* -------------------------------------------------------------------- */
1227
        /* Collect some additional generic information. */
1228
        /* -------------------------------------------------------------------- */
1229
        elemento.element_id = info.next_element_id - 1;
1230

  
1231
        elemento.offset = info.ftall - info.nElemBytes;
1232
        elemento.size = info.nElemBytes;
1233
        return elemento;
1234
    }
1235

  
1236
    private String numberFormat(String fmt, byte number) {
1237
        Formatter out = new Formatter();
1238
        return out.format(fmt, number).toString();
1239
    }
1240

  
1241
    private String numberFormat(String fmt, int number) {
1242
        Formatter out = new Formatter();
1243
        return out.format(fmt, number).toString();
1244
    }
1245

  
1246
    private String numberFormat(String fmt, double number) {
1247
        Formatter out = new Formatter();
1248
        return out.format(fmt, number).toString();
1249
    }
1250

  
1251
    private String dumpBuffer(byte[] buffer) {
1252
        StringBuffer out = new StringBuffer();
1253
        StringBuffer out1 = new StringBuffer();
1254
        Formatter out2 = new Formatter();
1255

  
1256
        int n = 0;
1257
        for (int i = 0; i < buffer.length; i++) {
1258
            int ch = buffer[i] & 0xff;
1259
            if (Character.isLetterOrDigit(ch)) {
1260
                out1.append(Character.valueOf((char) ch));
1261
            } else {
1262
                out1.append("-");
1263
            }
1264
            out2.format("0x%02X ", ch);
1265
            if (++n >= 8) {
1266
                n = 0;
1267
                out.append(out1);
1268
                out.append("|");
1269
                out.append(out2);
1270
                out.append("\n");
1271
                out1 = new StringBuffer();
1272
                out2 = new Formatter();
1273
            }
1274
        }
1275
        if (out1.length() > 0) {
1276
            out.append(out1);
1277
            out.append("|");
1278
            out.append(out2);
1279
            out.append("\n");
1280
        }
1281
        return out.toString();
1282
    }
1283

  
1284
    private double DGNParseIEEE(double d) {
1285
        byte[] temp = new byte[8];
1286
        int[] f = {0};
1287
        ByteUtils.doubleToBytes(d, temp, f);
1288

  
1289
        return DGNParseIEEE(temp);
1290
    }
1291

  
1292
    private double DGNParseIEEE(byte[] b) {
1293
        byte BYTE2 = b[7];
1294
        byte BYTE3 = b[6];
1295
        byte BYTE0 = b[5];
1296
        byte BYTE1 = b[4];
1297
        byte BYTE6 = b[3];
1298
        byte BYTE7 = b[2];
1299
        byte BYTE4 = b[1];
1300
        byte BYTE5 = b[0];
1301
        int sign;
1302
        int exponent;
1303
        int fraction;
1304
        double value;
1305
        int hi;
1306
        int lo;
1307
        int rndbits;
1308

  
1309
        /* -------------------------------------------------------------------- */
1310
        /* Save the sign of the double */
1311
        /* -------------------------------------------------------------------- */
1312
        byte[] temp = new byte[4];
1313
        byte[] temp1 = new byte[4];
1314

  
1315
        temp[3] = BYTE7;
1316
        temp[2] = BYTE6;
1317
        temp[1] = BYTE5;
1318
        temp[0] = BYTE4;
1319

  
1320
        int[] f = {0};
1321
        hi = ByteUtils.bytesToInt(temp, f);
1322
        sign = hi & 0x80000000;
1323

  
1324
        /* -------------------------------------------------------------------- */
1325
        /* Adjust the exponent so that we may work with it */
1326
        /* -------------------------------------------------------------------- */
1327
        exponent = hi >> 23;
1328
        exponent = exponent & 0x000000ff;
1329

  
1330
        if (exponent != 0) {
1331
            exponent = exponent - 129 + 1023;
1332
        }
1333

  
1334
        /* -------------------------------------------------------------------- */
1335
        /* Save the bits that we are discarding so we can round properly */
1336
        /* -------------------------------------------------------------------- */
1337
        temp[3] = BYTE3;
1338
        temp[2] = BYTE2;
1339
        temp[1] = BYTE1;
1340
        temp[0] = BYTE0;
1341

  
1342
        f[0] = 0;
1343
        lo = ByteUtils.bytesToInt(temp, f);
1344
        rndbits = lo & 0x00000007;
1345

  
1346
        lo = lo >> 3;
1347
        lo = (lo & 0x1fffffff) | (hi << 29);
1348

  
1349
        if (rndbits != 0) {
1350
            lo = lo | 0x00000001;
1351
        }
1352

  
1353
        /* -------------------------------------------------------------------- */
1354
        /* Shift the hi-order int over 3 and insert the exponent and sign */
1355
        /* -------------------------------------------------------------------- */
1356
        hi = hi >> 3;
1357
        hi = hi & 0x000fffff;
1358
        hi = hi | (exponent << 20) | sign;
1359
        f[0] = 0;
1360
        ByteUtils.intToBytes(hi, temp, f);
1361
        f[0] = 0;
1362
        ByteUtils.intToBytes(lo, temp1, f);
1363

  
1364
        byte[] result = new byte[8];
1365
        result[7] = temp1[3];
1366
        result[6] = temp1[2];
1367
        result[5] = temp1[1];
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff