svn-gvsig-desktop / tags / v1_1_Build_1015 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / Tiling.java @ 13679
History | View | Annotate | Download (8.48 KB)
1 | 1488 | luisw | /*
|
---|---|---|---|
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 | 6049 | nacho | 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 | 1488 | luisw | |
41 | public Tiling(int tileW, int tileH, Rectangle r) { |
||
42 | 6049 | nacho | int[] size = this.calcMaxTileSize(tileW, tileH, r); |
43 | tileMaxWidth = size[0];
|
||
44 | tileMaxHeight = size[1];
|
||
45 | 1488 | luisw | |
46 | int stepX, stepY;
|
||
47 | 4234 | nacho | int xProv, yProv;
|
48 | 1488 | luisw | int altoAux, anchoAux;
|
49 | |||
50 | 6049 | nacho | //Vamos a hacerlo en trozos de AxH
|
51 | 1488 | luisw | numCols = 1+(int) (r.width) / tileMaxWidth; |
52 | numRows = 1+(int) (r.height) / tileMaxHeight; |
||
53 | |||
54 | srcPts = new double[numCols*numRows][8]; |
||
55 | 1501 | luisw | tile = new Rectangle[numCols*numRows]; |
56 | 1488 | luisw | |
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 | 5979 | nacho | //Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
|
72 | 1488 | luisw | 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 | 1501 | luisw | tile[tileCnt] = new Rectangle(xProv, yProv, anchoAux+1, altoAux+1); |
84 | 1488 | luisw | |
85 | 5979 | nacho | xProv += tileMaxWidth; |
86 | 1488 | luisw | } |
87 | 5979 | nacho | yProv += tileMaxHeight; |
88 | 1488 | luisw | } |
89 | } |
||
90 | |||
91 | 6049 | nacho | /**
|
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 | 1488 | luisw | 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 | 1501 | luisw | public Rectangle getTileSz(int colNr, int rowNr) { |
141 | return tile[rowNr*numCols+colNr];
|
||
142 | 1488 | luisw | } |
143 | |||
144 | 1501 | luisw | public Rectangle getTile(int num) { |
145 | return tile[num];
|
||
146 | 1488 | luisw | } |
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 | 4234 | nacho | ViewPort[] viewPortList = null; |
176 | private void calcViewPort(ViewPort viewPort)throws NoninvertibleTransformException{ |
||
177 | viewPortList = new ViewPort[numCols*numRows];
|
||
178 | |||
179 | 5979 | nacho | /*if(viewPort.getImageWidth() < width && viewPort.getImageHeight() < height){
|
180 | 4234 | nacho | viewPortList[0] = viewPort;
|
181 | return;
|
||
182 | 5979 | nacho | }*/
|
183 | 4234 | nacho | |
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 | 1488 | luisw | public ViewPort getTileViewPort(ViewPort viewPort, int tileNr) throws NoninvertibleTransformException { |
232 | 4234 | nacho | /*if(viewPortList == null)
|
233 | this.calcViewPort(viewPort);
|
||
234 | return viewPortList[tileNr];*/
|
||
235 | 5979 | nacho | |
236 | if(tile.length == 1) |
||
237 | return viewPort;
|
||
238 | |||
239 | 1488 | luisw | double [] dstPts = new double[8]; |
240 | double [] srcPts = getTilePts(tileNr); |
||
241 | 1501 | luisw | Rectangle tile = getTile(tileNr);
|
242 | 1488 | luisw | //Rectangle newRect = new Rectangle((int)srcPts[0], (int)srcPts[1], tileSz[0], tileSz[1]);
|
243 | |||
244 | mat.inverseTransform(srcPts, 0, dstPts, 0, 4); |
||
245 | 1501 | luisw | 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 | 1488 | luisw | //Extent extent = new Extent(rectCuadricula);
|
251 | |||
252 | ViewPort vp = viewPort.cloneViewPort(); |
||
253 | 1501 | luisw | vp.setImageSize(tile.getSize()); |
254 | //vp.setOffset(tile.getLocation());
|
||
255 | 1488 | luisw | vp.setExtent(rectCuadricula); |
256 | vp.setAffineTransform(mat); |
||
257 | |||
258 | if (debug)
|
||
259 | System.out.println("Tiling.print(): tile "+tileNr+" de " |
||
260 | + getNumTiles() + |
||
261 | 1501 | luisw | "\n, Extent = "+vp.getAdjustedExtent() + " tile: " |
262 | + tile); |
||
263 | 1488 | luisw | |
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 |