|
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];
|