Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / util / DefaultRasterUtils.java @ 4436

History | View | Annotate | Download (21.7 KB)

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
package org.gvsig.raster.util;
23

    
24
import java.awt.Dimension;
25
import java.awt.geom.AffineTransform;
26
import java.awt.geom.NoninvertibleTransformException;
27
import java.awt.geom.Point2D;
28
import java.awt.geom.Rectangle2D;
29
import java.io.IOException;
30
import java.util.List;
31

    
32
import org.gvsig.fmap.dal.coverage.RasterLibrary;
33
import org.gvsig.fmap.dal.coverage.RasterLocator;
34
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
35
import org.gvsig.fmap.dal.coverage.datastruct.BufferHistogram;
36
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
37
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
38
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
39
import org.gvsig.raster.impl.datastruct.BufferHistogramImpl;
40
import org.gvsig.raster.impl.datastruct.ExtentImpl;
41
import org.gvsig.raster.impl.store.rmf.RmfBlocksManager;
42
import org.gvsig.raster.impl.store.serializer.GeoInfoRmfSerializer;
43
import org.gvsig.raster.roi.ROI;
44
/**
45
 * Raster utilities without gvSIG dependencies
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 */
48
public class DefaultRasterUtils implements RasterUtils {
49
        public static final int MAX_BYTE_BIT_VALUE  = 255;
50
        public static final int MAX_SHORT_BIT_VALUE = 65535;
51

    
52
        public boolean loadInMemory(RasterDataStore datasource) {
53
                return (datasource.getFileSize() < (RasterLibrary.cacheSize * 1048576));
54
        }
55

    
56
        public boolean isBufferTooBig(double[] coords, int bands) {
57
                int w = (int)Math.abs(coords[2] - coords[0]);
58
                int h = (int)Math.abs(coords[3] - coords[1]);
59

    
60
                long windowSize = w * h * bands;
61
                return (windowSize > (RasterLibrary.cacheSize * 1048576));
62
        }
63

    
64
        public boolean isBufferTooBig(double[] coords, double resolution, int bands) {
65
                double wPx = (coords[0] - coords[2]) / resolution;
66
                double hPx = (coords[1] - coords[3]) / resolution;
67
                return isBufferTooBig(new double[]{0, 0, wPx, hPx}, bands);
68
        }
69

    
70
        // ---------------------------------------------------------------
71
        // TIPOS DE DATOS
72

    
73
        public int getRasterBufTypeFromMrSIDType(int mrsidType){
74
                switch (mrsidType) {
75
                        case 0: return Buffer.TYPE_UNDEFINED;// INVALID
76
                        case 1:// UINT8
77
                        case 2: return Buffer.TYPE_BYTE;// SINT8
78
                        case 3:// UINT16
79
                        case 4: return Buffer.TYPE_SHORT;// SINT16
80
                        case 5:// UINT32
81
                        case 6: return Buffer.TYPE_INT;// SINT32
82
                        case 7: return Buffer.TYPE_FLOAT;// FLOAT32
83
                        case 8: return Buffer.TYPE_DOUBLE;// FLOAT64
84
                }
85
                return Buffer.TYPE_UNDEFINED;
86
        }
87

    
88
        public int getBytesFromRasterBufType(int rasterBufType) {
89
                switch (rasterBufType) {
90
                        case Buffer.TYPE_BYTE: return 1;
91
                        case Buffer.TYPE_USHORT:
92
                        case Buffer.TYPE_SHORT: return 2;
93
                        case Buffer.TYPE_INT:
94
                        case Buffer.TYPE_FLOAT:
95
                        case Buffer.TYPE_IMAGE: return 4;
96
                        case Buffer.TYPE_DOUBLE: return 8;
97
                }
98
                return 0; // TYPE_UNDEFINED
99
        }
100

    
101
        public long getBytesFromRaster(int width, int height,
102
                        int rasterType, int nBands) {
103
                int typeSize = getBytesFromRasterBufType(rasterType);
104
                return (long) width * (long) height * nBands * typeSize;
105
        }
106

    
107
        public String typesToString(int type) {
108
                switch (type) {
109
                        case Buffer.TYPE_IMAGE:
110
                                return new String("Image");
111

    
112
                        case Buffer.TYPE_BYTE:
113
                                return new String("Byte");
114

    
115
                        case Buffer.TYPE_DOUBLE:
116
                                return new String("Double");
117

    
118
                        case Buffer.TYPE_FLOAT:
119
                                return new String("Float");
120

    
121
                        case Buffer.TYPE_INT:
122
                                return new String("Integer");
123

    
124
                        case Buffer.TYPE_USHORT:
125
                        case Buffer.TYPE_SHORT:
126
                                return new String("Short");
127
                        case Buffer.TYPE_UNDEFINED:
128
                                return new String("Undefined");
129
                }
130
                return null;
131
        }
132

    
133
        public String parserGdalProj(String proj) {
134
                if (proj == null)
135
                        return "";
136
                String[] list = proj.split(",");
137
                int level = 0;
138
                for (int i = 0; i < list.length; i++) {
139
                        if (list[i].indexOf("[") >= 0) {
140
                                level++;
141
                                String spaces = "";
142
                                for (int j = 0; j < level; j++)
143
                                        spaces += "&nbsp;&nbsp;";
144
                                list[i] = spaces + list[i];
145
                        }
146
                        if (list[i].indexOf("]]") >= 0)
147
                                level = level - 2;
148
                        else
149
                                if (list[i].indexOf("]") >= 0)
150
                                        level--;
151
                }
152
                StringBuffer str = new StringBuffer();
153
                for (int i = 0; i < list.length; i++)
154
                        if (i < list.length)
155
                                if (i + 1 < list.length && list[i + 1].indexOf("[") >= 0)
156
                                        str.append(list[i] + ",<BR>");
157
                                else
158
                                        str.append(list[i] + ",");
159
                return str.toString();
160
        }
161

    
162
        // ---------------------------------------------------------------
163
        // CONVERSI?N DE COORDENADAS
164

    
165
        public Rectangle2D getPxRectFromMapRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D window) {
166
                double widthWC = extent.getWidth();
167
                double heightWC = extent.getHeight();
168

    
169
                double wWindowWC = Math.abs(window.getMaxX() - window.getMinX());
170
                double hWindowWC = Math.abs(window.getMaxY() - window.getMinY());
171

    
172
                double wWindowPx = ((wWindowWC * widthPx) / widthWC);
173
                double hWindowPx = ((hWindowWC * heightPx) / heightWC);
174

    
175
                double initDistanceX = Math.abs(window.getMinX() - extent.getMinX());
176
                double initDistanceY = Math.abs(window.getMaxY() - extent.getMaxY());
177

    
178
                double initPxX = ((initDistanceX * widthPx) / widthWC);
179
                double initPxY = ((initDistanceY * heightPx) / heightWC);
180

    
181
                Rectangle2D pxRec = new Rectangle2D.Double(initPxX, initPxY, wWindowPx, hWindowPx);
182
                return pxRec;
183
        }
184

    
185
        public Rectangle2D getMapRectFromPxRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D pxWindow) {
186
                double wWindowWC = ((pxWindow.getWidth() * extent.getWidth()) / widthPx);
187
                double hWindowWC = ((pxWindow.getHeight() * extent.getHeight()) / heightPx);
188

    
189
                double initWCX = extent.getMinX() + ((pxWindow.getMinX() * extent.getWidth()) / widthPx);
190
                double initWCY = extent.getMaxY() - ((pxWindow.getMinY() * extent.getHeight()) / heightPx);
191

    
192
                Rectangle2D mapRec = new Rectangle2D.Double(initWCX, initWCY - hWindowWC, wWindowWC, hWindowWC);
193
                return mapRec;
194
        }
195

    
196
        public Point2D worldPointToRaster(Point2D p, Extent ext, int pxWidth, int pxHeight) {
197
                double x = p.getX() - ext.getMin().getX();
198
                double y = p.getY() - ext.getMin().getY();
199
                int pxX = (int) ((x * pxWidth) / ext.width());
200
                int pxY = (int) ((y * pxHeight) / ext.height());
201
                return new Point2D.Double(pxX, pxY);
202
        }
203

    
204
        public boolean intersects(Extent e1, Extent e2, AffineTransform at) throws NoninvertibleTransformException {
205
                Point2D ulPxE1 = new Point2D.Double();
206
                Point2D lrPxE1 = new Point2D.Double();
207
                Point2D ulPxE2 = new Point2D.Double();
208
                Point2D lrPxE2 = new Point2D.Double();
209

    
210
                at.inverseTransform(new Point2D.Double(e1.getULX(), e1.getULY()), ulPxE1);
211
                at.inverseTransform(new Point2D.Double(e1.getLRX(), e1.getLRY()), lrPxE1);
212
                at.inverseTransform(new Point2D.Double(e2.getULX(), e2.getULY()), ulPxE2);
213
                at.inverseTransform(new Point2D.Double(e2.getLRX(), e2.getLRY()), lrPxE2);
214

    
215
                        if (((ulPxE1.getX() <= lrPxE2.getX()) && (lrPxE1.getX() >= lrPxE2.getX()) ||
216
                                         (ulPxE1.getX() <= ulPxE2.getX()) && (lrPxE1.getX() >= ulPxE2.getX()) ||
217
                                         (ulPxE1.getX() >= ulPxE2.getX()) && (lrPxE1.getX() <= lrPxE2.getX())) &&
218
                                        ((ulPxE1.getY() <= lrPxE2.getY()) && (lrPxE1.getY() >= lrPxE2.getY()) ||
219
                                         (ulPxE1.getY() <= ulPxE2.getY()) && (lrPxE1.getY() >= ulPxE2.getY()) ||
220
                                         (ulPxE1.getY() >= ulPxE2.getY()) && (lrPxE1.getY() <= lrPxE2.getY())))
221
                        return true;
222
                return false;
223
        }
224

    
225
        public Extent intersection(Extent e1, Extent e2) {
226
                if( (e1.getMin().getX() > e2.getMax().getX()) ||
227
                        (e1.getMax().getX() < e2.getMin().getX()) ||
228
                        (e1.getMin().getY() > e2.getMax().getY()) ||
229
                        (e1.getMax().getY() < e2.getMin().getY())) {
230
                        return null;
231
                }
232

    
233
                double ulx = Math.max(e1.getULX(), e2.getULX());
234
                double uly = Math.min(e1.getULY(), e2.getULY());
235
                double lrx = Math.min(e1.getLRX(), e2.getLRX());
236
                double lry = Math.max(e1.getLRY(), e2.getLRY());
237

    
238
                return new ExtentImpl(ulx, uly, lrx, lry);
239
        }
240

    
241
        public boolean isInside(Point2D p1, Extent e1, AffineTransform at) {
242
                // Convertimos los puntos a coordenadas pixel con la matriz de
243
                // transformaci?n
244
                Point2D p1Px = new Point2D.Double();
245
                Point2D ulPx = new Point2D.Double();
246
                Point2D lrPx = new Point2D.Double();
247
                try {
248
                        at.inverseTransform(p1, p1Px);
249
                        at.inverseTransform(new Point2D.Double(e1.getULX(), e1.getULY()), ulPx);
250
                        at.inverseTransform(new Point2D.Double(e1.getLRX(), e1.getLRY()), lrPx);
251
                } catch (NoninvertibleTransformException e) {
252
                        return false;
253
                }
254

    
255
                // Comprobamos si el punto est? dentro
256
                return ((p1Px.getX() >= ulPx.getX()) && (p1Px.getX() <= lrPx.getX()) &&
257
                                                (p1Px.getY() >= ulPx.getY()) && (p1Px.getY() <= lrPx.getY()));
258
        }
259

    
260
        public boolean isInside(Extent e1, Extent e2) {
261
                return ((e1.getMin().getX() >= e2.getMin().getX()) &&
262
                                (e1.getMin().getY() >= e2.getMin().getY()) &&
263
                                (e1.getMax().getX() <= e2.getMax().getX()) &&
264
                                (e1.getMax().getY() <= e2.getMax().getY()));
265
        }
266

    
267
        public boolean isInside(Point2D p1, Extent e1) {
268
                return ((p1.getX() >= e1.getMin().getX()) && (p1.getX() <= e1.getMax().getX()) && (p1.getY() >= e1.getMin().getY())) && (p1.getY() <= e1.getMax().getY());
269
        }
270

    
271
        public boolean isOutside(Extent e1, Extent ref) {
272
                return ((e1.getMin().getX() > ref.getMax().getX()) || (e1.getMin().getY() > ref.getMax().getY()) ||
273
                                                (e1.getMax().getX() < ref.getMin().getX()) || (e1.getMax().getY() < ref.getMin().getY()));
274
        }
275

    
276
        public boolean compareExtents(Extent e1, Extent e2) {
277
                return ((e1.getMin().getX() == e2.getMin().getX()) && (e1.getMin().getY() == e2.getMin().getY()) &&
278
                                                (e1.getMax().getX() == e2.getMax().getX())) && (e1.getMax().getY() == e2.getMax().getY());
279
        }
280

    
281
        public double[] cornersToWorldFile(Point2D[] esq, Dimension size) {
282
                double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
283
                double x1 = esq[0].getX(), y1 = esq[0].getY();
284
                double x2 = esq[1].getX(), y2 = esq[1].getY();
285
                double x3 = esq[2].getX(), y3 = esq[2].getY();
286
                double x4 = esq[3].getX(), y4 = esq[3].getY();
287
                // A: X-scale
288
                a = Math.abs(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) / size.getWidth());
289

    
290
                // E: negative Y-scale
291
                e = -Math.abs(Math.sqrt((x1 - x4) * (x1 - x4) + (y1 - y4) * (y1 - y4)) / size.getHeight());
292

    
293
                // C, F: upper-left coordinates
294
                c = x1;
295
                f = y1;
296

    
297
                // B & D: rotation parameters
298
                b = (a * size.getWidth() + c - x3) / size.getHeight() * -1;
299
                d = (e * size.getHeight() + f - y3) / size.getWidth() * -1;
300

    
301
                double[] wf = { a, d, b, e, c, f };
302
                return wf;
303
        }
304

    
305
        public void adjustToPixelSize(Point2D[] points, Point2D dim) {
306
                for (int i = 0; i < points.length; i++) {
307
                        if (points[i].getX() < 0)
308
                                points[i].setLocation(0, points[i].getY());
309
                        if (((int)points[i].getX()) > (dim.getX() - 1))
310
                                points[i].setLocation(dim.getX() - 1, points[i].getY());
311
                        if (points[i].getY() < 0)
312
                                points[i].setLocation(points[i].getX(), 0);
313
                        if (((int)points[i].getY()) > (dim.getY() - 1))
314
                                points[i].setLocation(points[i].getX(), dim.getY() - 1);
315
                }
316
        }
317

    
318
        // ---------------------------------------------------------------
319
        // VARIOS
320

    
321
        /**
322
         * Gets the exception trace
323
         * @param e
324
         * @return the exception trace
325
         */
326
        public String getTrace(Exception e) {
327
                Throwable throwable = e;
328
                String r = "";
329
                StackTraceElement[] elemList = throwable.getStackTrace();
330
                for (int i = 0; i < elemList.length; i++) {
331
                        r += "   !!!-" + elemList[i].toString() + "\n";
332
                }
333

    
334
                while(throwable.getCause() != null) {
335
                        elemList = throwable.getCause().getStackTrace();
336
                        for (int i = 0; i < elemList.length; i++) {
337
                                r += "   !!!-" + elemList[i].toString() + "\n";
338
                        }
339
                        throwable = throwable.getCause();
340
                }
341
                return r;
342
        }
343

    
344
        public String formatTime(long time) {
345
                int days = 0;
346
                int hours = 0;
347
                int minuts = 0;
348
                int seconds = (int) (time / 1000D);
349
                if (seconds >= 60) {
350
                        minuts = (seconds / 60);
351
                        seconds = (seconds - (minuts * 60));
352
                        if (minuts >= 60) {
353
                                hours = (minuts / 60);
354
                                minuts = (minuts - (hours * 60));
355
                                if (hours >= 24) {
356
                                        days = (hours / 24);
357
                                        hours = (hours - (days * 24));
358
                                }
359
                        }
360
                }
361
                StringBuffer s = new StringBuffer();
362
                if (days != 0)
363
                        s.append(days + " d ");
364
                if (hours != 0)
365
                        s.append(hours + " h ");
366
                if (minuts != 0)
367
                        s.append(minuts + " min ");
368
                if (seconds != 0)
369
                        s.append(seconds + " s ");
370
                if (s.length() == 0)
371
                        s.append(" < 1s");
372
                return s.toString();
373
        }
374

    
375
        public String[] getCoord(double minx, double miny, double maxx, double maxy, int dec) {
376
                String[] coordPx = new String[4];
377
                int indexPoint = String.valueOf(minx).indexOf('.');
378
                try {
379
                        coordPx[0] = String.valueOf(minx).substring(0, indexPoint + dec);
380
                } catch (StringIndexOutOfBoundsException ex) {
381
                        coordPx[0] = String.valueOf(minx);
382
                }
383
                indexPoint = String.valueOf(miny).indexOf('.');
384
                try {
385
                        coordPx[1] = String.valueOf(miny).substring(0, indexPoint + dec);
386
                } catch (StringIndexOutOfBoundsException ex) {
387
                        coordPx[1] = String.valueOf(miny);
388
                }
389
                indexPoint = String.valueOf(maxx).indexOf('.');
390
                try {
391
                        coordPx[2] = String.valueOf(maxx).substring(0, indexPoint + dec);
392
                } catch (StringIndexOutOfBoundsException ex) {
393
                        coordPx[2] = String.valueOf(maxx);
394
                }
395
                indexPoint = String.valueOf(maxy).indexOf('.');
396
                try {
397
                        coordPx[3] = String.valueOf(maxy).substring(0, indexPoint + dec);
398
                } catch (StringIndexOutOfBoundsException ex) {
399
                        coordPx[3] = String.valueOf(maxy);
400
                }
401
                return coordPx;
402
        }
403

    
404
        public Extent calculateAdjustedView(Extent extToAdj, Extent imgExt) {
405
                double vx = extToAdj.minX();
406
                double vy = extToAdj.minY();
407
                double vx2 = extToAdj.maxX();
408
                double vy2 = extToAdj.maxY();
409

    
410
                if (extToAdj.minX() < imgExt.minX())
411
                        vx = imgExt.minX();
412

    
413
                if (extToAdj.minY() < imgExt.minY())
414
                        vy = imgExt.minY();
415

    
416
                if (extToAdj.maxX() > imgExt.maxX())
417
                        vx2 = imgExt.maxX();
418

    
419
                if (extToAdj.maxY() > imgExt.maxY())
420
                        vy2 = imgExt.maxY();
421

    
422
                return new ExtentImpl(vx, vy, vx2, vy2);
423
        }
424

    
425
        public Extent calculateAdjustedView(Extent extToAdj, AffineTransform at, double w, double h) {
426
                        // Obtenemos los cuatro puntos de la petici?n de origen
427
                Point2D src_ul = new Point2D.Double(extToAdj.getULX(), extToAdj.getULY());
428
                Point2D src_lr = new Point2D.Double(extToAdj.getLRX(), extToAdj.getLRY());
429
        Point2D ul = new Point2D.Double();
430
        Point2D lr = new Point2D.Double();
431

    
432
                // Los convertimos a coordenadas pixel con la matriz de transformaci?n
433
                try {
434
                        at.inverseTransform(src_ul, ul);
435
                        at.inverseTransform(src_lr, lr);
436
                } catch (NoninvertibleTransformException e) {
437
                        return extToAdj;
438
                }
439

    
440
                // Ajustamos a la dimensi?n del raster en pixeles
441
                if (ul.getX() < 0)
442
                        ul.setLocation(0, ul.getY());
443
                if (ul.getX() >= w)
444
                        ul.setLocation(w, ul.getY());
445
                if (ul.getY() < 0)
446
                        ul.setLocation(ul.getX(), 0);
447
                if (ul.getY() >= h)
448
                        ul.setLocation(ul.getX(), h);
449

    
450
                if (lr.getX() < 0)
451
                        lr.setLocation(0, lr.getY());
452
                if (lr.getX() >= w)
453
                        lr.setLocation(w, lr.getY());
454
                if (lr.getY() < 0)
455
                        lr.setLocation(lr.getX(), 0);
456
                if (lr.getY() >= h)
457
                        lr.setLocation(lr.getX(), h);
458

    
459
                // Lo convertimos a coordenadas reales nuevamente
460
        Point2D real_ul = new Point2D.Double();
461
        Point2D real_lr = new Point2D.Double();
462
                at.transform(ul, real_ul);
463
                at.transform(lr, real_lr);
464
                return new ExtentImpl(real_ul, real_lr);
465
        }
466

    
467
        public void saveGeoInfo(String outRmf, AffineTransform at, Point2D dim) throws IOException {
468
                RmfBlocksManager manager = new RmfBlocksManager(outRmf + ".rmf");
469
                GeoInfoRmfSerializer ser3 = new GeoInfoRmfSerializer(at, dim);
470
                manager.addClient(ser3);
471
                manager.write();
472
        }
473

    
474
        /**
475
         * Obtiene el extent m?ximo de todas las ROIs pasadas por par?metro.
476
         * @param rois Lista de ROIs para calcular la extensi?n m?xima que ocupan
477
         * @return Entent m?ximo
478
         */
479
        public Extent getROIsMaximunExtent(List<ROI> rois) {
480
                double minx = 0, miny = 0, maxx = 0, maxy = 0;
481
                for (int i = 0; i < rois.size(); i++) {
482
                        Extent ext = rois.get(i).getROIExtent();
483
                        if(i == 0) {
484
                                minx = ext.minX();
485
                                miny = ext.minY();
486
                                maxx = ext.maxX();
487
                                maxy = ext.maxY();
488
                        } else {
489
                                if(ext.minX() < minx)
490
                                        minx = ext.minX();
491
                                if(ext.minY() < miny)
492
                                        miny = ext.minY();
493
                                if(ext.maxX() > maxx)
494
                                        maxx = ext.maxX();
495
                                if(ext.maxY() > maxy)
496
                                        maxy = ext.maxY();
497
                        }
498
                }
499
                return RasterLocator.getManager().getDataStructFactory().createExtent(minx, miny, maxx, maxy);
500
        }
501

    
502

    
503
        /**
504
         * Convierte un histograma al rango de valores de RGB, en pocas palabras
505
         * aplica una operacion 0xff a cada pixel para quitar los numeros negativos
506
         * y desplazarlos a su rango visual.
507
         * @param histogram
508
         */
509
        public BufferHistogram convertHistogramToRGB(BufferHistogram histogram) {
510
                if (histogram == null || !(histogram instanceof BufferHistogramImpl))
511
                        return null;
512

    
513
                BufferHistogramImpl histImp = (BufferHistogramImpl)histogram;
514

    
515
                if (histImp.getDataType() != Buffer.TYPE_BYTE)
516
                        return histogram;
517

    
518
                double min = histImp.getMin(0);
519
                double max = histImp.getMax(0);
520

    
521
                long table2[][] = histImp.getTable();
522

    
523
                long newTable[][] = new long[table2.length][table2[0].length];
524

    
525
                // Ponemos a cero todos los valores
526
                for (int i = 0; i < table2.length; i++)
527
                        for (int j = 0; j < table2[i].length; j++)
528
                                newTable[i][j] = 0;
529

    
530
                // Sumamos en la posicion calculada nueva el valor correspondiente
531
                for (int i = 0; i < table2.length; i++) {
532
                        for (int j = 0; j < table2[i].length; j++) {
533
                                double val = ((j * (max - min)) / 255) + min;
534
                                int pos = ((int) val) & 0xff;
535
                                if (pos < 0)
536
                                        pos = 0;
537
                                if (pos >= newTable[i].length)
538
                                        pos = newTable[i].length - 1;
539

    
540
                                newTable[i][pos] += table2[i][j];
541
                        }
542
                }
543

    
544
                double mins[] = new double[histImp.getNumBands()];
545
                double maxs[] = new double[histImp.getNumBands()];
546

    
547
                for (int i = 0; i < mins.length; i++) {
548
                        mins[i] = 0;
549
                        maxs[i] = 255;
550
                }
551

    
552
                BufferHistogramImpl histogramNew = new BufferHistogramImpl(histImp.getNumBands(), mins, maxs, Buffer.TYPE_BYTE);
553

    
554
                histogramNew.setTable(newTable);
555

    
556
                return histogramNew;
557
        }
558

    
559
        public void copyToBuffer(Buffer bufResult, Extent tileExtent,
560
                        Buffer buf, Extent ex, double rel, boolean hasAlphaBand) {
561
                double distx = Math.abs(ex.getULX() - tileExtent.getULX());
562
                double disty = Math.abs(ex.getULY() - tileExtent.getULY());
563
                int distpxx = (int)Math.round(distx / rel);
564
                int distpxy = (int)Math.round(disty / rel);
565
                int lastBandNumber = bufResult.getBandCount() - 1;
566

    
567
                //Para BYTE la ?ltima banda es de transparencia por lo que en esa banda en las zonas donde hay imagen
568
                //hay que ponerle el valor 255 para que aparezcan visibles
569
                if(bufResult.getDataType() == Buffer.TYPE_BYTE) {
570
                        for (int iBand = 0; iBand < lastBandNumber; iBand++) {
571
                                if(iBand == 0) {
572
                                        for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
573
                                                for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
574
                                                        bufResult.setElem(i, j, iBand, buf.getElemByte(i - distpxy, j - distpxx, iBand));
575
                                                        bufResult.setElem(i, j, lastBandNumber, (byte)255);
576
                                                }
577
                                        }
578
                                } else {
579
                                        for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
580
                                                for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
581
                                                        bufResult.setElem(i, j, iBand, buf.getElemByte(i - distpxy, j - distpxx, iBand));
582
                                                }
583
                                        }
584
                                }
585
                        }
586
                        //Si la imagen original tenia banda de transparencia hay que copiar los valores de transparencia que no son cero
587
                        if(hasAlphaBand) {
588
                                for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
589
                                        for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
590
                                                byte value = buf.getElemByte(i - distpxy, j - distpxx, lastBandNumber);
591
                                                if(value != 255)
592
                                                        bufResult.setElem(i, j, lastBandNumber, value);
593
                                        }
594
                                }
595
                        }
596
                }
597

    
598
                //En el resto de casos no se usa banda de transparencia sino que las zonas del tile fuera de la imagen
599
                //se inicializaron previamente a NoData
600

    
601
                if(bufResult.getDataType() == Buffer.TYPE_SHORT) {
602
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++) {
603
                                for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
604
                                        for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
605
                                                bufResult.setElem(i, j, iBand, buf.getElemShort(i - distpxy, j - distpxx, iBand));
606
                                        }
607
                                }
608
                        }
609
                }
610
                if(bufResult.getDataType() == Buffer.TYPE_INT) {
611
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++) {
612
                                for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
613
                                        for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
614
                                                bufResult.setElem(i, j, iBand, buf.getElemInt(i - distpxy, j - distpxx, iBand));
615
                                        }
616
                                }
617
                        }
618
                }
619
                if(bufResult.getDataType() == Buffer.TYPE_FLOAT) {
620
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++) {
621
                                for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
622
                                        for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
623
                                                bufResult.setElem(i, j, iBand, buf.getElemFloat(i - distpxy, j - distpxx, iBand));
624
                                        }
625
                                }
626
                        }
627
                }
628
                if(bufResult.getDataType() == Buffer.TYPE_DOUBLE) {
629
                        for (int iBand = 0; iBand < buf.getBandCount(); iBand++) {
630
                                for (int i = distpxy; (i < bufResult.getHeight() && (i - distpxy) < buf.getHeight()); i++) {
631
                                        for (int j = distpxx; (j < bufResult.getWidth() && (j - distpxx) < buf.getWidth()); j++) {
632
                                                bufResult.setElem(i, j, iBand, buf.getElemDouble(i - distpxy, j - distpxx, iBand));
633
                                        }
634
                                }
635
                        }
636
                }
637
        }
638

    
639
}