root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / Tiling.java @ 10977
History | View | Annotate | Download (8.43 KB)
1 | 1488 | luisw | /*
|
---|---|---|---|
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 | 6049 | nacho | 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 | 1488 | luisw | |
38 | public Tiling(int tileW, int tileH, Rectangle r) { |
||
39 | 6049 | nacho | int[] size = this.calcMaxTileSize(tileW, tileH, r); |
40 | tileMaxWidth = size[0];
|
||
41 | tileMaxHeight = size[1];
|
||
42 | 1488 | luisw | |
43 | int stepX, stepY;
|
||
44 | 4234 | nacho | int xProv, yProv;
|
45 | 1488 | luisw | int altoAux, anchoAux;
|
46 | |||
47 | 6049 | nacho | //Vamos a hacerlo en trozos de AxH
|
48 | 1488 | luisw | numCols = 1+(int) (r.width) / tileMaxWidth; |
49 | numRows = 1+(int) (r.height) / tileMaxHeight; |
||
50 | |||
51 | srcPts = new double[numCols*numRows][8]; |
||
52 | 1501 | luisw | tile = new Rectangle[numCols*numRows]; |
53 | 1488 | luisw | |
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 | 5979 | nacho | //Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
|
69 | 1488 | luisw | 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 | 1501 | luisw | tile[tileCnt] = new Rectangle(xProv, yProv, anchoAux+1, altoAux+1); |
81 | 1488 | luisw | |
82 | 5979 | nacho | xProv += tileMaxWidth; |
83 | 1488 | luisw | } |
84 | 5979 | nacho | yProv += tileMaxHeight; |
85 | 1488 | luisw | } |
86 | } |
||
87 | |||
88 | 6049 | nacho | /**
|
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 | 1488 | luisw | 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 | 1501 | luisw | public Rectangle getTileSz(int colNr, int rowNr) { |
138 | return tile[rowNr*numCols+colNr];
|
||
139 | 1488 | luisw | } |
140 | |||
141 | 1501 | luisw | public Rectangle getTile(int num) { |
142 | return tile[num];
|
||
143 | 1488 | luisw | } |
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 | 4234 | nacho | ViewPort[] viewPortList = null; |
173 | private void calcViewPort(ViewPort viewPort)throws NoninvertibleTransformException{ |
||
174 | viewPortList = new ViewPort[numCols*numRows];
|
||
175 | |||
176 | 5979 | nacho | /*if(viewPort.getImageWidth() < width && viewPort.getImageHeight() < height){
|
177 | 4234 | nacho | viewPortList[0] = viewPort;
|
178 | return;
|
||
179 | 5979 | nacho | }*/
|
180 | 4234 | nacho | |
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 | 1488 | luisw | public ViewPort getTileViewPort(ViewPort viewPort, int tileNr) throws NoninvertibleTransformException { |
229 | 4234 | nacho | /*if(viewPortList == null)
|
230 | this.calcViewPort(viewPort);
|
||
231 | return viewPortList[tileNr];*/
|
||
232 | 5979 | nacho | |
233 | if(tile.length == 1) |
||
234 | return viewPort;
|
||
235 | |||
236 | 1488 | luisw | double [] dstPts = new double[8]; |
237 | double [] srcPts = getTilePts(tileNr); |
||
238 | 1501 | luisw | Rectangle tile = getTile(tileNr);
|
239 | 1488 | luisw | //Rectangle newRect = new Rectangle((int)srcPts[0], (int)srcPts[1], tileSz[0], tileSz[1]);
|
240 | |||
241 | mat.inverseTransform(srcPts, 0, dstPts, 0, 4); |
||
242 | 1501 | luisw | 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 | 1488 | luisw | //Extent extent = new Extent(rectCuadricula);
|
248 | |||
249 | ViewPort vp = viewPort.cloneViewPort(); |
||
250 | 1501 | luisw | vp.setImageSize(tile.getSize()); |
251 | //vp.setOffset(tile.getLocation());
|
||
252 | 1488 | luisw | vp.setExtent(rectCuadricula); |
253 | vp.setAffineTransform(mat); |
||
254 | |||
255 | if (debug)
|
||
256 | System.out.println("Tiling.print(): tile "+tileNr+" de " |
||
257 | + getNumTiles() + |
||
258 | 1501 | luisw | "\n, Extent = "+vp.getAdjustedExtent() + " tile: " |
259 | + tile); |
||
260 | 1488 | luisw | |
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 |