Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1014 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / Tiling.java @ 13593

History | View | Annotate | Download (8.48 KB)

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

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

    
12
import org.cresques.px.Extent;
13

    
14
import com.iver.cit.gvsig.fmap.ViewPort;
15

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

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

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

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

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

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

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

    
292