Statistics
| Revision:

root / branches / v2_0_0_prep / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / Tiling.java @ 21200

History | View | Annotate | Download (8.71 KB)

1
/*
2
 * Created on 16-feb-2005
3
 */
4
package org.gvsig.fmap.mapcontext.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 org.gvsig.fmap.mapcontext.ViewPort;
12

    
13

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

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

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

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

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

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

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

    
290