svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / util / RasterUtilities.java @ 12767
History | View | Annotate | Download (22.6 KB)
1 |
package org.gvsig.raster.util; |
---|---|
2 |
|
3 |
import java.awt.Dimension; |
4 |
import java.awt.geom.AffineTransform; |
5 |
import java.awt.geom.Dimension2D; |
6 |
import java.awt.geom.NoninvertibleTransformException; |
7 |
import java.awt.geom.Point2D; |
8 |
import java.awt.geom.Rectangle2D; |
9 |
import java.io.BufferedOutputStream; |
10 |
import java.io.BufferedReader; |
11 |
import java.io.DataOutputStream; |
12 |
import java.io.File; |
13 |
import java.io.FileInputStream; |
14 |
import java.io.FileNotFoundException; |
15 |
import java.io.FileOutputStream; |
16 |
import java.io.FileReader; |
17 |
import java.io.IOException; |
18 |
import java.io.InputStream; |
19 |
import java.io.OutputStream; |
20 |
|
21 |
import org.gvsig.raster.buffer.RasterBuffer; |
22 |
import org.gvsig.raster.datastruct.Extent; |
23 |
|
24 |
import es.gva.cit.jgdal.Gdal; |
25 |
|
26 |
/**
|
27 |
*
|
28 |
* @author Nacho Brodin (nachobrodin@gmail.com)
|
29 |
*
|
30 |
*/
|
31 |
public class RasterUtilities { |
32 |
public static final int MAX_BYTE_BIT_VALUE = 255; |
33 |
public static final int MAX_SHORT_BIT_VALUE = 65535; |
34 |
|
35 |
//---------------------------------------------------------------
|
36 |
//TIPOS DE DATOS
|
37 |
|
38 |
/**
|
39 |
* Conversi?n de los tipos de datos de gdal a los tipos de datos de
|
40 |
* RasterBuf
|
41 |
* @param gdalType Tipo de dato de gdal
|
42 |
* @return Tipo de dato de RasterBuf
|
43 |
*/
|
44 |
public static int getRasterBufTypeFromGdalType(int gdalType){ |
45 |
switch(gdalType){
|
46 |
case 1:return RasterBuffer.TYPE_BYTE;//GDT_BYTE |
47 |
case 2://GDT_UInt16 |
48 |
case 8://GDT_CInt16 |
49 |
case 3:return RasterBuffer.TYPE_SHORT;//GDT_Int16 |
50 |
case 4://GDT_UInt32 |
51 |
case 9://GDT_CInt32 |
52 |
case 5:return RasterBuffer.TYPE_INT;//GDT_Int32 |
53 |
case 10://GDT_CFloat32 |
54 |
case 6:return RasterBuffer.TYPE_FLOAT;//GDT_Float32 |
55 |
case 11://GDT_CFloat64 |
56 |
case 7:return RasterBuffer.TYPE_DOUBLE;//GDT_Float64 |
57 |
} |
58 |
return RasterBuffer.TYPE_UNDEFINED;
|
59 |
} |
60 |
|
61 |
/**
|
62 |
* Conversi?n de los tipos de datos de RasterBuf en los de gdal.
|
63 |
* @param rasterBufType Tipo de dato de RasterBuf
|
64 |
* @return Tipo de dato de Gdal
|
65 |
*/
|
66 |
public static int getGdalTypeFromRasterBufType(int rasterBufType){ |
67 |
switch(rasterBufType){
|
68 |
case RasterBuffer.TYPE_BYTE:return Gdal.GDT_Byte; |
69 |
case RasterBuffer.TYPE_USHORT: return Gdal.GDT_UInt16; |
70 |
case RasterBuffer.TYPE_SHORT: return Gdal.GDT_Int16; |
71 |
case RasterBuffer.TYPE_INT: return Gdal.GDT_Int32; |
72 |
case RasterBuffer.TYPE_FLOAT: return Gdal.GDT_Float32; |
73 |
case RasterBuffer.TYPE_DOUBLE: return Gdal.GDT_Float64; |
74 |
case RasterBuffer.TYPE_UNDEFINED: return Gdal.GDT_Unknown; |
75 |
case RasterBuffer.TYPE_IMAGE: return Gdal.GDT_Byte; |
76 |
} |
77 |
return Gdal.GDT_Unknown;
|
78 |
} |
79 |
|
80 |
/**
|
81 |
* Conversi?n de los tipos de datos de MrSID a los tipos de datos de
|
82 |
* RasterBuf
|
83 |
* @param mrsidType Tipo de dato de MrSID
|
84 |
* @return Tipo de dato de RasterBuf
|
85 |
*/
|
86 |
public static int getRasterBufTypeFromMrSIDType(int mrsidType){ |
87 |
switch(mrsidType){
|
88 |
case 0:return RasterBuffer.TYPE_UNDEFINED;//INVALID |
89 |
case 1://UINT8 |
90 |
case 2:return RasterBuffer.TYPE_BYTE;//SINT8 |
91 |
case 3://UINT16 |
92 |
case 4:return RasterBuffer.TYPE_SHORT;//SINT16 |
93 |
case 5://UINT32 |
94 |
case 6:return RasterBuffer.TYPE_INT;//SINT32 |
95 |
case 7:return RasterBuffer.TYPE_FLOAT;//FLOAT32 |
96 |
case 8:return RasterBuffer.TYPE_DOUBLE;//FLOAT64 |
97 |
} |
98 |
return RasterBuffer.TYPE_UNDEFINED;
|
99 |
} |
100 |
|
101 |
/**
|
102 |
* Obtiene el n?mero de bytes que ocupa un tipo de dato concreto.
|
103 |
* Los tipos de datos son los utilizados en RasterBuffer
|
104 |
* @param rasterBufType Tipo de dato del que se solicita el n?mero de bytes ocupados
|
105 |
* @return
|
106 |
*/
|
107 |
public static int getBytesFromRasterBufType(int rasterBufType){ |
108 |
switch(rasterBufType){
|
109 |
case RasterBuffer.TYPE_BYTE:return 1; |
110 |
case RasterBuffer.TYPE_USHORT:
|
111 |
case RasterBuffer.TYPE_SHORT: return 2; |
112 |
case RasterBuffer.TYPE_INT:
|
113 |
case RasterBuffer.TYPE_FLOAT:
|
114 |
case RasterBuffer.TYPE_IMAGE: return 4; |
115 |
case RasterBuffer.TYPE_DOUBLE: return 8; |
116 |
} |
117 |
return 0; //TYPE_UNDEFINED |
118 |
} |
119 |
|
120 |
/**
|
121 |
* Convierte un tipo de dato a cadena
|
122 |
* @param type Tipo de dato
|
123 |
* @return cadena que representa el tipo de dato
|
124 |
*/
|
125 |
public static String typesToString(int type) { |
126 |
switch (type) {
|
127 |
case RasterBuffer.TYPE_IMAGE:
|
128 |
return new String("Image"); |
129 |
|
130 |
case RasterBuffer.TYPE_BYTE:
|
131 |
return new String("Byte"); |
132 |
|
133 |
case RasterBuffer.TYPE_DOUBLE:
|
134 |
return new String("Double"); |
135 |
|
136 |
case RasterBuffer.TYPE_FLOAT:
|
137 |
return new String("Float"); |
138 |
|
139 |
case RasterBuffer.TYPE_INT:
|
140 |
return new String("Integer"); |
141 |
|
142 |
case RasterBuffer.TYPE_USHORT:
|
143 |
case RasterBuffer.TYPE_SHORT:
|
144 |
return new String("Short"); |
145 |
} |
146 |
|
147 |
return null; |
148 |
} |
149 |
|
150 |
/**
|
151 |
* Parseo de las proyecciones que genera gdal para meter espaciados y saltos de l?nea HTML
|
152 |
* @param proj Proyecci?n
|
153 |
* @return Cadena con la proyecci?n parseada
|
154 |
*/
|
155 |
public static String parserGdalProj(String proj){ |
156 |
if(proj == null) |
157 |
return ""; |
158 |
String[] list = proj.split(","); |
159 |
int level = 0; |
160 |
for(int i = 0; i < list.length; i++){ |
161 |
if(list[i].indexOf("[") >= 0){ |
162 |
level ++; |
163 |
String spaces = ""; |
164 |
for(int j = 0; j < level; j++) |
165 |
spaces += " ";
|
166 |
list[i] = spaces + list[i]; |
167 |
} |
168 |
if(list[i].indexOf("]]") >= 0) |
169 |
level = level - 2;
|
170 |
else if(list[i].indexOf("]") >= 0) |
171 |
level --; |
172 |
} |
173 |
StringBuffer str = new StringBuffer(); |
174 |
for(int i = 0; i < list.length; i++){ |
175 |
if(i < list.length){
|
176 |
if(i + 1 < list.length && list[i + 1].indexOf("[") >= 0) |
177 |
str.append(list[i] + ",<BR>");
|
178 |
else
|
179 |
str.append(list[i] + ",");
|
180 |
} |
181 |
} |
182 |
return str.toString();
|
183 |
} |
184 |
|
185 |
//---------------------------------------------------------------
|
186 |
//ESPACIO DE COLOR
|
187 |
|
188 |
/**
|
189 |
* Descompone un entero que representa un ARGB en sus 4 valores byte
|
190 |
* Obtiene un array de 4 elementos donde el elemento 0 es el Rojo, el 1 es el
|
191 |
* verde, el 2 el azul y el 3 el alpha.
|
192 |
* @param rgb Entero con el valor ARGB a descomponer;
|
193 |
* @return Array de cuatro elementos
|
194 |
*/
|
195 |
public static byte[] getARGBFromIntToByteArray(int rgb){ |
196 |
byte[] b = new byte[4]; |
197 |
b[0] = (byte)((rgb & 0x00ff0000) >> 16); |
198 |
b[1] = (byte)((rgb & 0x0000ff00) >> 8); |
199 |
b[2] = (byte)(rgb & 0x000000ff); |
200 |
b[3] = (byte)((rgb & 0xff000000) >> 24); |
201 |
return b;
|
202 |
} |
203 |
|
204 |
/**
|
205 |
* Descompone un entero que representa un ARGB en sus 4 valores byte
|
206 |
* Obtiene un array de 4 elementos donde el elemento 0 es el Rojo, el 1 es el
|
207 |
* verde, el 2 el azul y el 3 el alpha.
|
208 |
* @param rgb Entero con el valor ARGB a descomponer;
|
209 |
* @return
|
210 |
*/
|
211 |
public static int[] getARGBFromIntToIntArray(int rgb){ |
212 |
int[] i = new int[4]; |
213 |
i[0] = (((rgb & 0x00ff0000) >> 16) & 0xff); |
214 |
i[1] = (((rgb & 0x0000ff00) >> 8) & 0xff); |
215 |
i[2] = ((rgb & 0x000000ff) & 0xff); |
216 |
i[3] = (((rgb & 0xff000000) >> 24) & 0xff); |
217 |
return i;
|
218 |
} |
219 |
|
220 |
/**
|
221 |
* Obtiene un entero con los valores ARGB pasados por par?metro
|
222 |
* @param a Valor de alpha
|
223 |
* @param r Valor del rojo
|
224 |
* @param g Valor del verde
|
225 |
* @param b Valor del azul
|
226 |
* @return entero con la mezcla de valores
|
227 |
*/
|
228 |
public static int getIntFromARGB(int a, int r, int g, int b){ |
229 |
return (((a & 0xff) << 24) + ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff)); |
230 |
} |
231 |
|
232 |
//---------------------------------------------------------------
|
233 |
//CONVERSI?N DE COORDENADAS
|
234 |
|
235 |
/**
|
236 |
* Convierte una ventana en coordenadas del mundo real a sus coordenadas relativas en pixels teniendo
|
237 |
* en cuenta que la coordenada superior izquierda es 0,0 y la inferior derecha es maxX y maY
|
238 |
* @param extent Extent de la imagen original
|
239 |
* @param widthPx Ancho en pixeles de la imagen original
|
240 |
* @param heightPx Alto en pixeles de la imagen original
|
241 |
* @param window Ventana en coordenadas reales a transportar a coordenadas pixel
|
242 |
* @return Ventana en coordenadas pixel
|
243 |
*/
|
244 |
public static Rectangle2D getPxRectFromMapRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D window){ |
245 |
double widthWC = extent.getWidth();
|
246 |
double heightWC = extent.getHeight();
|
247 |
|
248 |
double wWindowWC = Math.abs(window.getMaxX() - window.getMinX()); |
249 |
double hWindowWC = Math.abs(window.getMaxY() - window.getMinY()); |
250 |
|
251 |
double wWindowPx = ((wWindowWC * widthPx) / widthWC);
|
252 |
double hWindowPx = ((hWindowWC * heightPx) / heightWC);
|
253 |
|
254 |
double initDistanceX = Math.abs(window.getMinX() - extent.getMinX()); |
255 |
double initDistanceY = Math.abs(window.getMaxY() - extent.getMaxY()); |
256 |
|
257 |
double initPxX = ((initDistanceX * widthPx) / widthWC);
|
258 |
double initPxY = ((initDistanceY * heightPx) / heightWC);
|
259 |
|
260 |
Rectangle2D pxRec = new Rectangle2D.Double( initPxX, |
261 |
initPxY, |
262 |
wWindowPx, |
263 |
hWindowPx); |
264 |
return pxRec;
|
265 |
} |
266 |
|
267 |
/**
|
268 |
* Convierte una ventana en coordenadas del mundo real a sus coordenadas relativas en pixels teniendo
|
269 |
* en cuenta que la coordenada superior izquierda es 0,0 y la inferior derecha es maxX y maY
|
270 |
* @param extent Extent de la imagen original
|
271 |
* @param widthPx Ancho en pixeles de la imagen original
|
272 |
* @param heightPx Alto en pixeles de la imagen original
|
273 |
* @param window Ventana en coordenadas reales a transportar a coordenadas pixel
|
274 |
* @return Ventana en coordenadas pixel
|
275 |
*/
|
276 |
public static Rectangle2D getMapRectFromPxRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D pxWindow){ |
277 |
double wWindowWC = ((pxWindow.getWidth() * extent.getWidth()) / widthPx);
|
278 |
double hWindowWC = ((pxWindow.getHeight() * extent.getHeight()) / heightPx);
|
279 |
|
280 |
double initWCX = extent.getMinX() + ((pxWindow.getMinX() * extent.getWidth()) / widthPx);
|
281 |
double initWCY = extent.getMaxY() - ((pxWindow.getMinY() * extent.getHeight()) / heightPx);
|
282 |
|
283 |
Rectangle2D mapRec = new Rectangle2D.Double(initWCX, |
284 |
initWCY - hWindowWC, |
285 |
wWindowWC, |
286 |
hWindowWC); |
287 |
return mapRec;
|
288 |
} |
289 |
|
290 |
/**
|
291 |
* Convierte un punto en coordenadas del mundo a coordenadas pixel
|
292 |
* @param p Punto a convertir
|
293 |
* @param ext Extent completo de la imagen
|
294 |
* @return Punto en coordenadas pixel
|
295 |
*/
|
296 |
public static Point2D worldPointToRaster(Point2D p, Extent ext, int pxWidth, int pxHeight) { |
297 |
double x = p.getX() - ext.getMin().getX();
|
298 |
double y = p.getY() - ext.getMin().getY();
|
299 |
int pxX = (int)((x * pxWidth) / ext.width()); |
300 |
int pxY = (int)((y * pxHeight) / ext.height()); |
301 |
return new Point2D.Double(pxX, pxY); |
302 |
} |
303 |
|
304 |
/**
|
305 |
* Ajusta la extensi?n pasada por par?metro a los valores m?ximos y m?nimos de la
|
306 |
* imagen. Esto sirve para que la petici?n al driver nunca sobrepase los l?mites
|
307 |
* de la imagen tratada aunque la vista donde se dibuje sea de mayor tama?o.
|
308 |
*
|
309 |
* @param imgExt Extent completo de la vista donde se va a dibujar.
|
310 |
* @param extToAdj Extent a ajustar.
|
311 |
* @return adjustedExtent Extent ajustado a m?ximos y m?nimos
|
312 |
*/
|
313 |
public static Extent calculateAdjustedView(Extent extToAdj, Extent imgExt) { |
314 |
double vx = extToAdj.minX();
|
315 |
double vy = extToAdj.minY();
|
316 |
double vx2 = extToAdj.maxX();
|
317 |
double vy2 = extToAdj.maxY();
|
318 |
|
319 |
if (extToAdj.minX() < imgExt.minX())
|
320 |
vx = imgExt.minX(); |
321 |
|
322 |
if (extToAdj.minY() < imgExt.minY())
|
323 |
vy = imgExt.minY(); |
324 |
|
325 |
if (extToAdj.maxX() > imgExt.maxX())
|
326 |
vx2 = imgExt.maxX(); |
327 |
|
328 |
if (extToAdj.maxY() > imgExt.maxY())
|
329 |
vy2 = imgExt.maxY(); |
330 |
|
331 |
return new Extent(vx, vy, vx2, vy2); |
332 |
} |
333 |
|
334 |
/**
|
335 |
* Ajusta la extensi?n pasada por par?metro a los valores m?ximos y m?nimos de la
|
336 |
* imagen. Esto sirve para que la petici?n al driver nunca sobrepase los l?mites
|
337 |
* de la imagen tratada aunque la vista donde se dibuje sea de mayor tama?o. Este m?todo
|
338 |
* tiene en cuenta la rotaci?n aplicada al raster por lo que no ajustamos a un extent sino
|
339 |
* a una matriz de transformaci?n. Esta tiene los par?metros de traslaci?n, rotaci?n y
|
340 |
* escalado del raster destino. Esta matriz transforma coordenadas pixel a real y viceversa.
|
341 |
*
|
342 |
* @param imgExt Extent completo de la vista donde se va a dibujar.
|
343 |
* @param AffineTransform Matriz de transformaci?n del raster destino
|
344 |
* @return adjustedExtent Extent ajustado a m?ximos y m?nimos
|
345 |
*/
|
346 |
public static Extent calculateAdjustedView(Extent extToAdj, AffineTransform at, Dimension2D dim) { |
347 |
//Obtenemos los cuatro puntos de la petici?n de origen
|
348 |
Point2D ul = new Point2D.Double(extToAdj.getULX(), extToAdj.getULY()); |
349 |
Point2D lr = new Point2D.Double(extToAdj.getLRX(), extToAdj.getLRY()); |
350 |
|
351 |
//Los convertimos a coordenadas pixel con la matriz de transformaci?n
|
352 |
try {
|
353 |
at.inverseTransform(ul, ul); |
354 |
at.inverseTransform(lr, lr); |
355 |
} catch (NoninvertibleTransformException e) { |
356 |
return extToAdj;
|
357 |
} |
358 |
|
359 |
//Ajustamos a la dimensi?n del raster en pixeles
|
360 |
if (ul.getX() < 0) |
361 |
ul.setLocation(0, ul.getY());
|
362 |
if (ul.getX() >= dim.getWidth())
|
363 |
ul.setLocation(dim.getWidth(), ul.getY()); |
364 |
if (ul.getY() < 0) |
365 |
ul.setLocation(ul.getX(), 0);
|
366 |
if (ul.getY() >= dim.getHeight())
|
367 |
ul.setLocation(ul.getX(), dim.getHeight()); |
368 |
|
369 |
if (lr.getX() < 0) |
370 |
lr.setLocation(0, lr.getY());
|
371 |
if (lr.getX() >= dim.getWidth())
|
372 |
lr.setLocation(dim.getWidth(), lr.getY()); |
373 |
if (lr.getY() < 0) |
374 |
lr.setLocation(lr.getX(), 0);
|
375 |
if (lr.getY() >= dim.getHeight())
|
376 |
lr.setLocation(lr.getX(), dim.getHeight()); |
377 |
|
378 |
//Lo convertimos a coordenadas reales nuevamente
|
379 |
at.transform(ul, ul); |
380 |
at.transform(lr, lr); |
381 |
return new Extent(ul, lr); |
382 |
} |
383 |
|
384 |
/**
|
385 |
* Compara dos extents y devuelve true si son iguales
|
386 |
* @param e1 Extent a comparar
|
387 |
* @param e2 Extent a comparar
|
388 |
* @return true si los extents pasados por par?metro son iguales y false si no lo son
|
389 |
*/
|
390 |
public static boolean compareExtents(Extent e1, Extent e2){ |
391 |
return ((e1.getMin().getX() == e2.getMin().getX()) && (e1.getMin().getY() == e2.getMin().getY()) &&
|
392 |
(e1.getMax().getX() == e2.getMax().getX())) && (e1.getMax().getY() == e2.getMax().getY()); |
393 |
} |
394 |
|
395 |
/**
|
396 |
* Comprueba si un extent est? contenido dentro de otro y devuelve true en este caso.
|
397 |
* @param e1 Extent a comprobar si est? contenido en e2
|
398 |
* @param e2 Extent sobre el que se comprueba si e1 est? dentro
|
399 |
* @return true si e1 est? dentro de e1
|
400 |
*/
|
401 |
public static boolean isInside(Extent e1, Extent e2){ |
402 |
return ((e1.getMin().getX() >= e2.getMin().getX()) && (e1.getMin().getY() >= e2.getMin().getY()) &&
|
403 |
(e1.getMax().getX() <= e2.getMax().getX())) && (e1.getMax().getY() <= e2.getMax().getY()); |
404 |
} |
405 |
|
406 |
/**
|
407 |
* Comprueba si alguna parte de un extent est? fuera del extent que tenemos como referencia.
|
408 |
* @param e1 Extent a comprobar si est? fuera
|
409 |
* @param ref Extent de referencia
|
410 |
* @return Devuelve true si alguna parte de e1 cae fuera de ref y false si no tiene ninguna fuera.
|
411 |
*/
|
412 |
public static boolean isOutside(Extent e1, Extent ref){ |
413 |
return ((e1.getMin().getX() > ref.getMax().getX()) || (e1.getMin().getY() > ref.getMax().getY()) ||
|
414 |
(e1.getMax().getX() < ref.getMin().getX()) || (e1.getMax().getY() < ref.getMin().getY())); |
415 |
} |
416 |
|
417 |
/**
|
418 |
* Calcula los par?metros de un worl file a partir de las esquinas del raster.
|
419 |
* 1. X pixel size A
|
420 |
* 2. X rotation term D
|
421 |
* 3. Y rotation term B
|
422 |
* 4. Y pixel size E
|
423 |
* 5. X coordinate of upper left corner C
|
424 |
* 6. Y coordinate of upper left corner F
|
425 |
* where the real-world coordinates x',y' can be calculated from
|
426 |
* the image coordinates x,y with the equations
|
427 |
* x' = Ax + By + C and y' = Dx + Ey + F.
|
428 |
* The signs of the first 4 parameters depend on the orientation
|
429 |
* of the image. In the usual case where north is more or less
|
430 |
* at the top of the image, the X pixel size will be positive
|
431 |
* and the Y pixel size will be negative. For a south-up image,
|
432 |
* these signs would be reversed.
|
433 |
*
|
434 |
* You can calculate the World file parameters yourself based
|
435 |
* on the corner coordinates. The X and Y pixel sizes can be
|
436 |
* determined simply by dividing the distance between two
|
437 |
* adjacent corners by the number of columns or rows in the image.
|
438 |
* The rotation terms are calculated with these equations:
|
439 |
*
|
440 |
* # B = (A * number_of_columns + C - lower_right_x') / number_of_rows * -1
|
441 |
* # D = (E * number_of_rows + F - lower_right_y') / number_of_columns * -1
|
442 |
*
|
443 |
* @param corner (tl, tr, br, bl)
|
444 |
* @return
|
445 |
*/
|
446 |
public static double [] cornersToWorldFile(Point2D [] esq, Dimension size) { |
447 |
double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0; |
448 |
double x1 = esq[0].getX(), y1 = esq[0].getY(); |
449 |
double x2 = esq[1].getX(), y2 = esq[1].getY(); |
450 |
double x3 = esq[2].getX(), y3 = esq[2].getY(); |
451 |
double x4 = esq[3].getX(), y4 = esq[3].getY(); |
452 |
// A: X-scale
|
453 |
a = Math.abs( Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) |
454 |
/ size.getWidth()); |
455 |
|
456 |
// E: negative Y-scale
|
457 |
e = - Math.abs(Math.sqrt((x1 - x4) * (x1 - x4) + |
458 |
(y1 - y4) * (y1 - y4)) / size.getHeight()); |
459 |
|
460 |
// C, F: upper-left coordinates
|
461 |
c = x1; |
462 |
f = y1; |
463 |
|
464 |
// B & D: rotation parameters
|
465 |
b = (a * size.getWidth() + c - x3 ) / size.getHeight() * -1;
|
466 |
d = (e * size.getHeight() + f - y3 ) / size.getWidth() * -1;
|
467 |
|
468 |
double [] wf = {a, d, b, e, c, f}; |
469 |
return wf;
|
470 |
} |
471 |
|
472 |
//---------------------------------------------------------------
|
473 |
//TRATAMIENTO DE FICHEROS
|
474 |
|
475 |
/**
|
476 |
* Copia de ficheros
|
477 |
* @param pathOrig Ruta de origen
|
478 |
* @param pathDst Ruta de destino.
|
479 |
*/
|
480 |
public static void copyFile(String pathOrig, String pathDst) |
481 |
throws FileNotFoundException, IOException{ |
482 |
InputStream in;
|
483 |
OutputStream out;
|
484 |
|
485 |
if(pathOrig == null || pathDst == null){ |
486 |
System.err.println("Error en path"); |
487 |
return;
|
488 |
} |
489 |
|
490 |
File orig = new File(pathOrig); |
491 |
if(!orig.exists() || !orig.isFile() || !orig.canRead()){
|
492 |
System.err.println("Error en fichero de origen"); |
493 |
return;
|
494 |
} |
495 |
|
496 |
File dest = new File(pathDst); |
497 |
String file = pathOrig.substring(pathOrig.lastIndexOf(File.separator), pathOrig.length()); |
498 |
if(dest.isDirectory())
|
499 |
pathDst += file; |
500 |
|
501 |
in = new FileInputStream(pathOrig); |
502 |
out = new FileOutputStream(pathDst); |
503 |
|
504 |
byte[] buf = new byte[1024]; |
505 |
int len;
|
506 |
|
507 |
while ((len = in.read(buf)) > 0) |
508 |
out.write(buf, 0, len);
|
509 |
|
510 |
in.close(); |
511 |
out.close(); |
512 |
} |
513 |
|
514 |
/**
|
515 |
* Crea un fichero de georeferenciaci?n (world file) para un dataset determinado
|
516 |
* @param GdalDriver
|
517 |
* @param fileName Nombre completo del fichero de raster
|
518 |
* @param Extent
|
519 |
* @param pxWidth Ancho en p?xeles
|
520 |
* @param pxHeight Alto en p?xeles
|
521 |
* @return
|
522 |
* @throws IOException
|
523 |
*/
|
524 |
public static void createWorldFile(String fileName, Extent ext, int pxWidth, int pxHeight) throws IOException { |
525 |
File tfw = null; |
526 |
|
527 |
String extWorldFile = ".wld"; |
528 |
if(fileName.endsWith("tif")) |
529 |
extWorldFile = ".tfw";
|
530 |
if(fileName.endsWith("jpg") || fileName.endsWith("jpeg")) |
531 |
extWorldFile = ".jpgw";
|
532 |
|
533 |
tfw = new File(fileName.substring(0, fileName.lastIndexOf(".")) + extWorldFile); |
534 |
|
535 |
//Generamos un world file para gdal
|
536 |
DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) ); |
537 |
dos.writeBytes((ext.getMax().getX() - ext.getMin().getX()) / pxWidth + "\n");
|
538 |
dos.writeBytes("0.0\n");
|
539 |
dos.writeBytes("0.0\n");
|
540 |
dos.writeBytes((ext.getMin().getY() - ext.getMax().getY()) / pxHeight + "\n");
|
541 |
dos.writeBytes("" + ext.getMin().getX() + "\n"); |
542 |
dos.writeBytes("" + ext.getMax().getY() + "\n"); |
543 |
dos.close(); |
544 |
} |
545 |
|
546 |
/**
|
547 |
* Formatea en forma de cadena un tama?o dado en bytes. El resultado
|
548 |
* ser? una cadena con GB, MB, KB y B
|
549 |
* @param size tama?o a formatear
|
550 |
* @return cadena con la cantidad formateada
|
551 |
*/
|
552 |
public static String formatFileSize(long size){ |
553 |
double bytes = (double)size, kBytes = 0, mBytes = 0, gBytes = 0; |
554 |
if(size >= 1024){ |
555 |
kBytes = (double)(size / 1024D); |
556 |
bytes = (int)(size - (((int)kBytes) * 1024)); |
557 |
if(kBytes >= 1024){ |
558 |
mBytes = (double)(((int)kBytes) / 1024D); |
559 |
kBytes = (double)(((int)kBytes) - (((int)mBytes) * 1024)); |
560 |
if(mBytes >= 1024){ |
561 |
gBytes = (int)(((int)mBytes) / 1024); |
562 |
mBytes = (int)(((int)mBytes) - (gBytes * 1024)); |
563 |
} |
564 |
} |
565 |
} |
566 |
|
567 |
if(gBytes > 0) |
568 |
return MathUtils.format(gBytes, 1) + "G"; |
569 |
if(mBytes > 0) |
570 |
return MathUtils.format(mBytes, 1) + "M"; |
571 |
if(kBytes > 0) |
572 |
return MathUtils.format(kBytes, 1) + "K"; |
573 |
if(bytes != 0) |
574 |
return ((int)bytes) + ""; |
575 |
|
576 |
return ""; |
577 |
} |
578 |
|
579 |
/**
|
580 |
* Obtiene la extensi?n del fichero a partir de su nombre.
|
581 |
* @param file Nombre o ruta del fichero
|
582 |
* @return Cadena con la extensi?n que representa el tipo de fichero.
|
583 |
*/
|
584 |
public static String getExtensionFromFileName(String file) { |
585 |
return file.toLowerCase().substring(file.lastIndexOf(".") + 1); |
586 |
} |
587 |
|
588 |
/**
|
589 |
* Obtiene la codificaci?n de un fichero XML
|
590 |
* @param file Nombre del fichero XML
|
591 |
* @return Codificaci?n
|
592 |
*/
|
593 |
public static String readFileEncoding(String file){ |
594 |
FileReader fr;
|
595 |
String encoding = null; |
596 |
try {
|
597 |
fr = new FileReader(file); |
598 |
BufferedReader br = new BufferedReader(fr); |
599 |
char[] buffer = new char[100]; |
600 |
br.read(buffer); |
601 |
StringBuffer st = new StringBuffer(new String(buffer)); |
602 |
String searchText = "encoding=\""; |
603 |
int index = st.indexOf(searchText);
|
604 |
if (index >- 1) { |
605 |
st.delete(0, index+searchText.length());
|
606 |
encoding = st.substring(0, st.indexOf("\"")); |
607 |
} |
608 |
fr.close(); |
609 |
} catch(FileNotFoundException ex) { |
610 |
ex.printStackTrace(); |
611 |
} catch (IOException e) { |
612 |
e.printStackTrace(); |
613 |
} |
614 |
return encoding;
|
615 |
} |
616 |
|
617 |
//---------------------------------------------------------------
|
618 |
//VARIOS
|
619 |
|
620 |
/**
|
621 |
* Formatea el tiempo en milisegundos devolviendo un String en formato .
|
622 |
* dias, horas, minutos y segundos.
|
623 |
* @param time Tiempo en milisegundos
|
624 |
*/
|
625 |
public static String formatTime(long time) { |
626 |
int days = 0, hours = 0, minuts = 0, seconds = (int)(time / 1000D); |
627 |
if(seconds >= 60){ |
628 |
minuts = (int)(seconds / 60); |
629 |
seconds = (int)(seconds - (minuts * 60)); |
630 |
if(minuts >= 60){ |
631 |
hours = (int)(minuts / 1024); |
632 |
minuts = (int)(minuts - (hours * 60)); |
633 |
} |
634 |
} |
635 |
StringBuffer s = new StringBuffer(); |
636 |
if(hours != 0) |
637 |
s.append(hours+" H ");
|
638 |
if(minuts != 0) |
639 |
s.append(minuts+" Min ");
|
640 |
if(seconds != 0) |
641 |
s.append(seconds+" Sec ");
|
642 |
return s.toString();
|
643 |
} |
644 |
} |