Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / Tiling.java @ 11807

History | View | Annotate | Download (8.43 KB)

1
/*
2
 * Created on 16-feb-2005
3
 */
4
package com.iver.cit.gvsig.fmap.layers;
5

    
6
import java.awt.Rectangle;
7
import java.awt.geom.AffineTransform;
8
import java.awt.geom.NoninvertibleTransformException;
9
import java.awt.geom.Rectangle2D;
10

    
11
import com.iver.cit.gvsig.fmap.ViewPort;
12

    
13
/**
14
 * C?lculo de Partes (Tiles) en las que se divide un raster grande.
15
 * Se usa para imprimir rasters y capas raste remotas (WMS).
16
 * 
17
 * Para no pedir imagenes demasiado grandes, vamos
18
 * a hacer lo mismo que hace EcwFile: chunkear.
19
 * Llamamos a drawView con cuadraditos m?s peque?os
20
 * del BufferedImage ni caso, cuando se imprime viene con null
21
 * c?digo original de Fran Pe?arrubia
22
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
23
 */
24

    
25
public class Tiling {
26
        private static final int                MIN_SIZE = 50; //Tama?o m?nimo en pixeles del tile
27
        private boolean                                 debug = true;
28
        private int                                         tileMaxWidth, tileMaxHeight;
29
        private int                                         numRows, numCols;
30
        private double[][]                                 srcPts;
31
        private Rectangle[]                         tile;
32
        private double                                         width = 500, height = 500;        
33
        private AffineTransform                 mat;
34
        private ViewPort                                 vp;
35
                
36
        public Tiling(){}
37
        
38
        public Tiling(int tileW, int tileH, Rectangle r) {
39
                int[] size = this.calcMaxTileSize(tileW, tileH, r);
40
                tileMaxWidth = size[0];
41
                tileMaxHeight = size[1];
42
                
43
        int stepX, stepY;
44
        int xProv, yProv;
45
        int altoAux, anchoAux;
46
        
47
        //Vamos a hacerlo en trozos de AxH
48
        numCols = 1+(int) (r.width) / tileMaxWidth;
49
        numRows = 1+(int) (r.height) / tileMaxHeight;
50
        
51
        srcPts = new double[numCols*numRows][8];
52
        tile = new Rectangle[numCols*numRows];
53
        
54
            yProv = (int) r.y;
55
        for (stepY=0; stepY < numRows; stepY++) {
56
                    if ((yProv + tileMaxHeight) > r.getMaxY()) 
57
                            altoAux = (int) r.getMaxY() - yProv;
58
                    else
59
                            altoAux = tileMaxHeight;
60
                                        
61
                    xProv = (int) r.x;
62
                for (stepX=0; stepX < numCols; stepX++) {                        
63
                            if ((xProv + tileMaxWidth) > r.getMaxX()) 
64
                                    anchoAux = (int) r.getMaxX() - xProv;
65
                            else
66
                                    anchoAux = tileMaxWidth;
67
                        
68
                        //Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
69
                        int tileCnt = stepY*numCols+stepX;
70
                        // Parte que dibuja
71
                        srcPts[tileCnt][0] = xProv;
72
                        srcPts[tileCnt][1] = yProv;
73
                        srcPts[tileCnt][2] = xProv + anchoAux+1;
74
                        srcPts[tileCnt][3] = yProv;
75
                        srcPts[tileCnt][4] = xProv + anchoAux+1;
76
                        srcPts[tileCnt][5] = yProv + altoAux+1;
77
                        srcPts[tileCnt][6] = xProv;
78
                        srcPts[tileCnt][7] = yProv + altoAux+1;
79
                        
80
                        tile[tileCnt] = new Rectangle(xProv, yProv, anchoAux+1, altoAux+1);
81
                        
82
                                xProv += tileMaxWidth;        
83
                }                        
84
                yProv += tileMaxHeight;
85
        }                  
86
        }
87
        
88
        /**
89
         * Calcula el tama?o m?ximo de tile controlando que ning?n tile tenga menos de MIN_SIZE
90
         * pixeles
91
         * @param tileW Ancho del tile
92
         * @param tileH        Alto del tile
93
         * @param r Rectangulo que define el area de la imagen
94
         */
95
        public int[] calcMaxTileSize(int tileW, int tileH, Rectangle r){
96
                if(r.width < tileW || r.height < tileH){
97
                        int[] sizeTiles = {tileW, tileH};
98
                        return sizeTiles;
99
                }
100
                        
101
        int wLastCol = 0;
102
        tileW += MIN_SIZE;
103
                do{
104
                        tileW -= MIN_SIZE;
105
                int numCols = (int) (r.width / tileW);
106
                int w = 0;
107
                for(int i = 0; i < numCols; i++)
108
                        w += tileW;
109
                wLastCol = r.width - w;
110
                }while(wLastCol < MIN_SIZE && tileW > (MIN_SIZE * 2));
111
                
112
                int hLastRow = 0;
113
        tileH += MIN_SIZE;
114
                do{
115
                        tileH -= MIN_SIZE;
116
                int numRows = (int) (r.height / tileH);
117
                int h = 0;
118
                for(int i = 0; i < numRows; i++)
119
                        h += tileH;
120
                hLastRow = r.height - h;
121
                }while(hLastRow < MIN_SIZE && tileH > (MIN_SIZE * 2));
122
                
123
                tileMaxWidth = tileW;
124
                tileMaxHeight = tileH;
125
                int[] sizeTiles = {tileMaxWidth, tileMaxHeight};
126
                return sizeTiles;
127
        }
128
        
129
        public double [] getTilePts(int colNr, int rowNr) {
130
                return srcPts[rowNr*numCols+colNr];
131
        }
132
        
133
        public double [] getTilePts(int num) {
134
                return srcPts[num];
135
        }
136
        
137
        public Rectangle getTileSz(int colNr, int rowNr) {
138
                return tile[rowNr*numCols+colNr];
139
        }
140
        
141
        public Rectangle getTile(int num) {
142
                return tile[num];
143
        }
144
        
145
        /**
146
         * @return Returns the numCols.
147
         */
148
        public int getNumCols() {
149
                return numCols;
150
        }
151
        /**
152
         * @return Returns the numRows.
153
         */
154
        public int getNumRows() {
155
                return numRows;
156
        }
157
        
158
        public int getNumTiles() { return numRows*numCols; }
159
        /**
160
         * @return Returns the tileHeight.
161
         */
162
        public int getMaxTileHeight() {
163
                return tileMaxHeight;
164
        }
165
        /**
166
         * @return Returns the tileWidth.
167
         */
168
        public int getMaxTileWidth() {
169
                return tileMaxWidth;
170
        }
171
        
172
        ViewPort[] viewPortList = null;
173
        private void calcViewPort(ViewPort viewPort)throws NoninvertibleTransformException{
174
                viewPortList = new ViewPort[numCols*numRows];
175
                
176
                /*if(viewPort.getImageWidth() < width && viewPort.getImageHeight() < height){
177
                        viewPortList[0] = viewPort;
178
                        return;
179
                }*/
180
                
181
            int vpCnt = 0;
182

    
183
            double imgPxX = viewPort.getImageWidth();
184
            double dWcX = viewPort.getAdjustedExtent().getWidth();
185
            double tileWcW = (getTile(vpCnt).getSize().getWidth() * dWcX) / imgPxX;
186
            
187
            double imgPxY = viewPort.getImageHeight();
188
            double dWcY = viewPort.getAdjustedExtent().getHeight();
189
            double tileWcH = (getTile(vpCnt).getSize().getHeight() * dWcY) / imgPxY;
190
           
191
            viewPortList[0] = viewPort.cloneViewPort();
192
            viewPortList[0].setImageSize(getTile(vpCnt).getSize());
193
            viewPortList[0].setExtent(new Rectangle2D.Double(viewPort.getAdjustedExtent().getMinX(), viewPort.getAdjustedExtent().getMaxY() - tileWcH, tileWcW, tileWcH));
194
            viewPortList[0].setAffineTransform(mat);
195

    
196
            double wt = tileWcW;
197
            double ht = tileWcH;
198
            double xt = viewPort.getAdjustedExtent().getMinX();
199
            double yt = viewPort.getAdjustedExtent().getMaxY() - tileWcH;
200
            
201
            for (int stepY=0; stepY < numRows; stepY++) {
202
                    wt = tileWcW;
203
                    xt = viewPort.getAdjustedExtent().getMinX();
204
                    for (int stepX=0; stepX < numCols; stepX++) {
205
                            vpCnt = stepY*numCols+stepX;
206
                            if(vpCnt > 0){
207
                                    if(stepX > 0)
208
                                            xt += wt;
209
                                    if((xt + wt) > viewPort.getAdjustedExtent().getMaxX())
210
                                            wt = Math.abs(viewPort.getAdjustedExtent().getMaxX() - xt);
211

    
212
                                    viewPortList[vpCnt] = viewPort.cloneViewPort();
213
                                    viewPortList[vpCnt].setImageSize(getTile(vpCnt).getSize());
214
                                    viewPortList[vpCnt].setExtent(new Rectangle2D.Double(xt, yt, wt, ht));
215
                                    viewPortList[vpCnt].setAffineTransform(mat);
216

    
217
                            }
218
                            //System.out.println("ViewPort: "+vpCnt+" "+viewPortList[vpCnt].getAdjustedExtent()+" "+getTile(vpCnt).getSize());
219
                    }
220
                    if((yt - ht) < viewPort.getAdjustedExtent().getMinY()){
221
                            ht = Math.abs(yt - viewPort.getAdjustedExtent().getMinY());
222
                            yt = viewPort.getAdjustedExtent().getMinY();
223
                    }else
224
                            yt -= ht;
225
            }
226
        }
227
        
228
        public ViewPort getTileViewPort(ViewPort viewPort, int tileNr) throws NoninvertibleTransformException {
229
                /*if(viewPortList == null)
230
                        this.calcViewPort(viewPort);
231
                return viewPortList[tileNr];*/
232
                
233
                if(tile.length == 1)
234
                        return viewPort;
235
                
236
                double [] dstPts = new double[8];
237
                double [] srcPts = getTilePts(tileNr);
238
                Rectangle tile = getTile(tileNr);
239
                //Rectangle newRect = new Rectangle((int)srcPts[0], (int)srcPts[1], tileSz[0], tileSz[1]);
240
                
241
                mat.inverseTransform(srcPts, 0, dstPts, 0, 4);
242
                double x = dstPts[0], w = dstPts[2] - dstPts[0];
243
                double y = dstPts[1], h = dstPts[5] - dstPts[3];
244
                if (w < 0) { x = dstPts[2]; w = dstPts[0] - dstPts[2]; }
245
                if (h < 0) { y = dstPts[5]; h = dstPts[3] - dstPts[5]; }
246
                Rectangle2D.Double rectCuadricula = new Rectangle2D.Double(x, y, w, h); 
247
                //Extent extent = new Extent(rectCuadricula);
248
                
249
                ViewPort vp = viewPort.cloneViewPort();
250
                vp.setImageSize(tile.getSize());
251
                //vp.setOffset(tile.getLocation());
252
                vp.setExtent(rectCuadricula);
253
                vp.setAffineTransform(mat);
254
                
255
                if (debug)
256
                    System.out.println("Tiling.print(): tile "+tileNr+" de "
257
                            + getNumTiles() + 
258
                            "\n, Extent = "+vp.getAdjustedExtent() + " tile: "
259
                            + tile);
260

    
261
                return vp;
262
        }
263
        /**
264
         * @return Returns the mat.
265
         */
266
        public AffineTransform getAffineTransform() {
267
                return mat;
268
        }
269
        /**
270
         * @param mat The mat to set.
271
         */
272
        public void setAffineTransform(AffineTransform mat) {
273
                this.mat = mat;
274
        }
275
        /**
276
         * @return Returns the debug.
277
         */
278
        public boolean isDebug() {
279
                return debug;
280
        }
281
        /**
282
         * @param debug The debug to set.
283
         */
284
        public void setDebug(boolean debug) {
285
                this.debug = debug;
286
        }
287
}
288

    
289