Statistics
| Revision:

gvsig-raster / org.gvsig.raster.cache / trunk / org.gvsig.raster.cache / org.gvsig.raster.cache.lib.impl / src / main / java / org / gvsig / raster / cache / tile / impl / provider / DefaultCacheStruct.java @ 982

History | View | Annotate | Download (16.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.cache.tile.impl.provider;
23

    
24
import java.awt.geom.Point2D;
25
import java.awt.geom.Rectangle2D;
26
import java.util.ArrayList;
27

    
28
import org.gvsig.raster.cache.tile.Tile;
29
import org.gvsig.raster.cache.tile.TileCacheLocator;
30
import org.gvsig.raster.cache.tile.disk.ITileFileSystemStrategy;
31
import org.gvsig.raster.cache.tile.exception.TileBuildException;
32
import org.gvsig.raster.cache.tile.impl.TileImpl;
33
import org.gvsig.raster.cache.tile.provider.CacheStruct;
34

    
35
/**
36
 * Implementation for a structure of a cache
37
 * @author Nacho Brodin (nachobrodin@gmail.com)
38
 */
39
public class DefaultCacheStruct implements CacheStruct {
40
    private TileMatrixSet                 tileMatrixSet  = null;
41
    private ArrayList<TileMatrixLimits>   limits         = null;
42
    private String                        layerName      = null;
43
    private String                        uri            = null;
44
        private Rectangle2D                   worldExtent    = null;
45
        private String                        fileSuffix     = null;
46
        private String                        epsg           = null;
47
        private long                          fileSize       = 0;
48
        private double                        realPixelSize  = 0;
49
        private Rectangle2D                   layerExtent    = null;
50
    
51
    public DefaultCacheStruct(int typeOfCoords, 
52
                    int levels, 
53
                    Rectangle2D layerExtent, 
54
                    double pixelSize,
55
                    int tilePxWidth,
56
                    int tilePxHeight,
57
                    String uri,
58
                    String layerName,
59
                    ITileFileSystemStrategy strategy,
60
                    String baseDir,
61
                    String fileSuffix,
62
                    String epsg,
63
                    long size) {
64
            this.uri = uri;
65
            this.layerName = layerName;
66
            this.fileSuffix = fileSuffix;
67
            this.fileSize = size;
68
            this.realPixelSize = pixelSize;
69
            this.layerExtent = layerExtent;
70
            if(epsg != null && epsg.startsWith("EPSG:"))
71
                    this.epsg = epsg;
72
            
73
            //Coordenadas del mundo en geogr?ficas y planas
74
            
75
            if(typeOfCoords == CacheStruct.GEOGRAFIC) {
76
                    worldExtent = new Rectangle2D.Double(-180, -90, 360, 180);
77
            } 
78
            if(typeOfCoords == CacheStruct.FLAT) {
79
                    worldExtent = new Rectangle2D.Double(-20037508, -20037508, 40075016, 40075016);
80
            }
81
            
82
            double[] pixelSizeList = buildWorldMatrix(typeOfCoords, levels, tilePxWidth, tilePxHeight, worldExtent);
83
        buildLayerMatrix(levels, tilePxWidth, tilePxHeight, worldExtent, layerExtent, pixelSizeList, pixelSize);
84
    }
85
    
86
    private void buildLayerMatrix(int levels, 
87
                    int tilePxWidth, 
88
                    int tilePxHeight,
89
                    Rectangle2D worldExtent,
90
                    Rectangle2D layerExtent,
91
                    double[] pixelSizeList,
92
                    double maxPixelSize) {
93
            limits = new ArrayList<TileMatrixLimits>();
94

    
95
            for (int i = 0; i < levels; i++) {
96
                    //Calculo de tiles para ese nivel en la capa actual
97
                    int minTileCol = (int)(Math.abs(layerExtent.getMinX() - worldExtent.getMinX()) / pixelSizeList[i]) / tilePxWidth;
98
                    int minTileRow = (int)(Math.abs(layerExtent.getMaxY() - worldExtent.getMaxY()) / pixelSizeList[i]) / tilePxHeight;
99
                    int maxTileCol = (int)(Math.abs(layerExtent.getMaxX() - worldExtent.getMinX()) / pixelSizeList[i]) / tilePxWidth;
100
                    int maxTileRow = (int)(Math.abs(layerExtent.getMinY() - worldExtent.getMaxY()) / pixelSizeList[i]) / tilePxHeight;
101
                    
102
                    //int imageTileWidth = (int)Math.ceil((layerExtent.getWidth() / pixelSizeList[i]) / tilePxWidth);
103
                    //int imageTileHeight = (int)Math.ceil((layerExtent.getHeight() / pixelSizeList[i]) / tilePxHeight);
104
                    TileMatrixLimits limit = new TileMatrixLimits();
105
                    limit.setMinTileRow(minTileRow);
106
                    limit.setMinTileCol(minTileCol);
107
                    limit.setMaxTileRow(maxTileRow);
108
                    limit.setMaxTileCol(maxTileCol);
109
                    
110
                    //Calcula las coordenadas de la esquina superior izquierda del TileMatrixLimits
111
                    double ulx = worldExtent.getMinX() + (minTileCol * tilePxWidth * pixelSizeList[i]);
112
                    double uly = worldExtent.getMaxY() - (minTileRow * tilePxHeight * pixelSizeList[i]);
113
                    limit.getTileMatrix().setTopLeftCorner(new double[]{ulx, uly});
114
                    limit.getTileMatrix().setScaleDenominator(pixelSizeList[i]);
115
                    limit.getTileMatrix().setTileWidth(tilePxWidth);
116
                    limit.getTileMatrix().setTileHeight(tilePxHeight);
117
                    
118
                    limits.add(limit);
119
                    if(i == (levels - 1) || (maxPixelSize != Double.POSITIVE_INFINITY && maxPixelSize != Double.NEGATIVE_INFINITY && pixelSizeList[i] < maxPixelSize)) {
120
                            //System.out.println("Image res:" + maxPixelSize + " Real res:" + pixelSizeList[i]);
121
                            break;
122
                    }
123
            }
124
    }
125
    
126
    private double[] buildWorldMatrix(int typeOfCoords,
127
                    int levels, 
128
                    int tilePxWidth, 
129
                    int tilePxHeight,
130
                    Rectangle2D worldExtent) {
131
            double[] pixelSizeList = new double[levels];
132
            
133
            limits = new ArrayList<TileMatrixLimits>();
134
            tileMatrixSet = new TileMatrixSet();
135
            tileMatrixSet.setBbox(worldExtent);
136
            
137
            int nTilesWidth = 0;
138
            int nTilesHeight = 0;
139
                    
140
            for (int i = 0; i < levels; i++) {
141
                    TileMatrix tm = new TileMatrix();
142
                    tm.setTileWidth(tilePxWidth);
143
                    tm.setTileHeight(tilePxHeight);
144
                    if(i == 0) {
145
                            nTilesWidth = (typeOfCoords == CacheStruct.FLAT) ? 1 : 2;
146
                            nTilesHeight = 1;
147
                    } else {
148
                            nTilesWidth *= 2;
149
                            nTilesHeight *= 2;
150
                    }
151
                    
152
                    tm.setMatrixWidth(nTilesWidth);
153
                    tm.setMatrixHeight(nTilesHeight);
154
                    if((tilePxWidth * nTilesWidth) != 0)
155
                            pixelSizeList[i] = worldExtent.getWidth() / ((long)tilePxWidth * (long)nTilesWidth);
156
                    else
157
                            pixelSizeList[i] = 0;
158
                    //System.out.println("-Level:" + i + " " + nTilesWidth + " " + nTilesHeight + " " + pixelSizeList[i]);
159
                    tm.setScaleDenominator(pixelSizeList[i]);
160
                    tileMatrixSet.getTileMatrix().add(tm);
161
            }
162
            return pixelSizeList;
163
    }
164

    
165
    /*
166
     * (non-Javadoc)
167
     * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getNumberOfLevels()
168
     */
169
        public int getNumberOfLevels() {
170
                return tileMatrixSet.getTileMatrix().size();
171
        }
172

    
173
        /*
174
         * (non-Javadoc)
175
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getLayerName()
176
         */
177
        public String getLayerName() {
178
                return layerName;
179
        }
180

    
181
        /*
182
         * (non-Javadoc)
183
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getServerURL()
184
         */
185
        public String getServerURL() {
186
                return uri;
187
        }
188
        
189
        /*
190
         * (non-Javadoc)
191
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getFileSuffix()
192
         */
193
        public String getFileSuffix() {
194
                return fileSuffix;
195
        }
196

    
197
        /*
198
         * (non-Javadoc)
199
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileSizeByLevel(int)
200
         */
201
        public int[] getTileSizeByLevel(int level) {
202
                return new int[] {
203
                        tileMatrixSet.getTileMatrix().get(level).getTileWidth(),
204
                        tileMatrixSet.getTileMatrix().get(level).getTileHeight()
205
                };
206
        }
207
        
208
        /*
209
         * (non-Javadoc)
210
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileSizeInRealCoordsByLevel(int)
211
         */
212
        public double[] getTileSizeInRealCoordsByLevel(int level) {
213
                return new double[] {
214
                                getPixelSizeByLevel(level) * tileMatrixSet.getTileMatrix().get(level).getTileWidth(),
215
                                getPixelSizeByLevel(level) *  tileMatrixSet.getTileMatrix().get(level).getTileHeight()
216
                        };
217
        }
218

    
219
        /*
220
         * (non-Javadoc)
221
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getLayerWidthOfTileMatrixByLevel(int)
222
         */
223
        public int getLayerWidthOfTileMatrixByLevel(int level) {
224
                if(level < limits.size()) {
225
                        TileMatrixLimits l = limits.get(level);
226
                        return (l.getMaxTileRow() - l.getMinTileRow()) + 1;
227
                }
228
                return 0;
229
        }
230
        
231
        /*
232
         * (non-Javadoc)
233
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getLayerHeightOfTileMatrixByLevel(int)
234
         */
235
        public int getLayerHeightOfTileMatrixByLevel(int level) {
236
                if(level < limits.size()) {
237
                        TileMatrixLimits l = limits.get(level);
238
                        return (l.getMaxTileCol() - l.getMinTileCol()) + 1;
239
                }
240
                return 0;
241
        }
242

    
243
        /*
244
         * (non-Javadoc)
245
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getLayerInitXTilePositionByLevel(int)
246
         */
247
        public int getLayerInitXTilePositionByLevel(int level) {
248
                TileMatrixLimits l = limits.get(level);
249
                return l.getMinTileCol();
250
        }
251

    
252
        /*
253
         * (non-Javadoc)
254
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getLayerInitYTilePositionByLevel(int)
255
         */
256
        public int getLayerInitYTilePositionByLevel(int level) {
257
                TileMatrixLimits l = limits.get(level);
258
                return l.getMinTileRow();
259
        }
260

    
261
        /*
262
         * (non-Javadoc)
263
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getWorldHeightOfTileMatrixByLevel(int)
264
         */
265
        public long getWorldHeightOfTileMatrixByLevel(int level) {
266
                return tileMatrixSet.getTileMatrix().get(level).getMatrixWidth();
267
        }
268

    
269
        /*
270
         * (non-Javadoc)
271
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getWorldWidthOfTileMatrixByLevel(int)
272
         */
273
        public long getWorldWidthOfTileMatrixByLevel(int level) {
274
                return tileMatrixSet.getTileMatrix().get(level).getMatrixHeight();
275
        }
276
        
277
        /*
278
         * (non-Javadoc)
279
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getPixelSizeByLevel(int)
280
         */
281
        public double getPixelSizeByLevel(int level) {
282
                if(level < 0)
283
                        return realPixelSize;
284
                return tileMatrixSet.getTileMatrix().get(level).getScaleDenominator();
285
        }
286
        
287
        /*
288
         * (non-Javadoc)
289
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileExtent(org.gvsig.raster.cache.tile.Tile)
290
         */
291
        public Point2D[] getTileExtent(Tile tile) {
292
                return limits.get(tile.getLevel()).getTileExtent(tile.getRow(), tile.getCol());
293
        }
294
        
295
        /*
296
         * (non-Javadoc)
297
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileExtent(int, int, int)
298
         */
299
        public Point2D[] getTileExtent(int level, int col, int row) {
300
                return limits.get(level).getTileExtent(row, col);
301
        }
302
        
303
        /*
304
         * (non-Javadoc)
305
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileStructure(int, int, int, java.awt.geom.Point2D, java.awt.geom.Point2D)
306
         */
307
        public Tile getTileStructure(int level, int tileCol, int tileRow, Point2D ul, Point2D lr) throws TileBuildException  {
308
                int[] size = getTileSizeByLevel(level);
309
                Tile tile = TileCacheLocator.getManager().createTile(level, tileRow, tileCol);
310
                tile.setUl(ul);
311
                tile.setLr(lr);
312
                tile.setWidthPx(size[0]);
313
                tile.setHeightPx(size[1]);
314
                
315
                return tile;
316
        }
317
        
318
        /*
319
         * (non-Javadoc)
320
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileList(java.awt.geom.Rectangle2D)
321
         */
322
        public ArrayList<Tile> getTileList(Rectangle2D r) {
323
                int tilePxWidth = tileMatrixSet.getTileMatrix().get(0).getTileWidth();
324
                int tilePxHeight = tileMatrixSet.getTileMatrix().get(0).getTileHeight();
325
                int minTileCol = (int)(r.getX() / tilePxWidth);
326
                int minTileRow = (int)(r.getY() / tilePxHeight);
327
                int maxTileCol = (int)((r.getX() + r.getWidth()) / tilePxWidth);
328
                int maxTileRow = (int)((r.getY() + r.getHeight()) / tilePxHeight);
329
                double tileWCWidth = tilePxWidth * realPixelSize;
330
                double tileWCHeight = tilePxHeight * realPixelSize;
331
                
332
                //Calculo de tiles con sus coordenadas
333
                ArrayList<Tile> tileList = new ArrayList<Tile>();
334
                for (int i = minTileRow; i <= maxTileRow; i++) {
335
                        for (int j = minTileCol; j <= maxTileCol; j++) {
336
                                Point2D ulTile = new Point2D.Double(
337
                                                layerExtent.getMinX() + (tileWCWidth * j),
338
                                                layerExtent.getMaxY() - (tileWCHeight * i));
339
                                Point2D lrTile = new Point2D.Double(ulTile.getX() + tileWCWidth, ulTile.getY() - tileWCHeight);
340
                                Tile t = new TileImpl(tilePxWidth, tilePxHeight, i, j, ulTile, lrTile);
341
                                t.setLevel(-1);
342
                                int initTileX = tilePxWidth * j;
343
                                int initTileY = tilePxHeight * i;
344
                                Rectangle2D rTile = new Rectangle2D.Double(initTileX, initTileY, tilePxWidth, tilePxHeight);
345
                                t.setCoordsPx(rTile);
346
                                tileList.add(t);
347
                        }
348
                }
349
                return tileList;
350
        }
351
        
352
        /*
353
         * (non-Javadoc)
354
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getTileList(java.awt.geom.Point2D, java.awt.geom.Point2D)
355
         */
356
        public ArrayList<Tile> getTileList(Point2D ul, Point2D lr, double mtsPixelRequest) {
357
                //Selecci?n de nivel de resoluci?n
358
                int tilePxWidth = 0;
359
                int tilePxHeight = 0;
360
                double tileWCWidth = 0;
361
                double tileWCHeight = 0;
362
                int level = 0;
363
                double mtsPixelLevel = 0;
364
                for (int i = 0; i < tileMatrixSet.getTileMatrix().size(); i++) {
365
                        mtsPixelLevel = tileMatrixSet.getTileMatrix().get(i).getScaleDenominator();
366
                        if(mtsPixelRequest > mtsPixelLevel) {
367
                                level = Math.max(i, 0);
368
                                //Se ajusta al m?ximo nivel disponible para esa capa
369
                                if(level > (limits.size() - 1)) {
370
                                        level = limits.size() - 1;
371
                                        mtsPixelLevel = tileMatrixSet.getTileMatrix().get(level).getScaleDenominator();
372
                                }
373
                                
374
                                tilePxWidth = tileMatrixSet.getTileMatrix().get(level).getTileWidth();
375
                                tilePxHeight = tileMatrixSet.getTileMatrix().get(level).getTileHeight();
376
                                
377
                                //mtsPixelLevel = tileMatrixSet.getTileMatrix().get(i - 1).getScaleDenominator();
378
                                tileWCWidth = tilePxWidth * mtsPixelLevel;
379
                                tileWCHeight = tilePxHeight * mtsPixelLevel;
380
                                break;
381
                        }
382
                }
383
                
384
                //Calculo del rectangulo de tiles
385
                int minTileCol = (int)((Math.abs(ul.getX() - worldExtent.getMinX()) / mtsPixelLevel) / tilePxWidth);
386
                int minTileRow = (int)((Math.abs(ul.getY() - worldExtent.getMaxY()) / mtsPixelLevel) / tilePxHeight);
387
                double maxTC = ((Math.abs(lr.getX() - worldExtent.getMinX()) / mtsPixelLevel) / tilePxWidth);
388
                double maxTR = ((Math.abs(lr.getY() - worldExtent.getMaxY()) / mtsPixelLevel) / tilePxHeight);
389
                int maxTileCol = ((maxTC - ((int)maxTC)) == 0) ? (int)(maxTC - 1) : (int)maxTC;
390
                int maxTileRow = ((maxTR - ((int)maxTR)) == 0) ? (int)(maxTR - 1) : (int)maxTR;
391
                
392
                //Calculo de tiles con sus coordenadas
393
                ArrayList<Tile> tileList = new ArrayList<Tile>();
394
                for (int i = minTileRow; i <= maxTileRow; i++) {
395
                        for (int j = minTileCol; j <= maxTileCol; j++) {
396
                                Point2D ulTile = new Point2D.Double(
397
                                                worldExtent.getMinX() + (tileWCWidth * j),
398
                                                worldExtent.getMaxY() - (tileWCHeight * i));
399
                                Point2D lrTile = new Point2D.Double(ulTile.getX() + tileWCWidth, ulTile.getY() - tileWCHeight);
400
                                Tile t = new TileImpl(tilePxWidth, tilePxHeight, i, j, ulTile, lrTile);
401
                                t.setLevel(level);
402
                                tileList.add(t);
403
                        }
404
                }
405
                return tileList;
406
        }
407
        
408
        /*
409
         * (non-Javadoc)
410
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#compare(org.gvsig.raster.cache.tile.provider.CacheStruct)
411
         */
412
        public boolean compare(CacheStruct struct) {
413
                //Compara: n?mero de niveles, tama?o de tile, 
414
                //anchoXalto de la matriz, tama?o de pixel por nivel, 
415
                //coordenadas de al menos un tile de la matriz
416
                if(struct.getNumberOfLevels() == getNumberOfLevels()) {
417
                        for (int i = 0; i < getNumberOfLevels(); i++) {
418
                                if(        struct.getTileSizeByLevel(i)[0] == getTileSizeByLevel(i)[0] && 
419
                                        struct.getTileSizeByLevel(i)[1] == getTileSizeByLevel(i)[1] &&
420
                                        struct.getWorldHeightOfTileMatrixByLevel(i) == getWorldHeightOfTileMatrixByLevel(i) &&
421
                                        struct.getWorldWidthOfTileMatrixByLevel(i) == getWorldWidthOfTileMatrixByLevel(i) &&
422
                                        clipDecimals(struct.getPixelSizeByLevel(i), 2) == clipDecimals(getPixelSizeByLevel(i), 2) &&
423
                                        compareExtents(struct.getTileExtent(i, 0, 0), getTileExtent(i, 0, 0))) {
424
                                        return true;
425
                                }
426
                        }
427
                }
428
                return false;
429
        }
430
        
431
        /*
432
         * (non-Javadoc)
433
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getEPSG()
434
         */
435
        public String getEPSG() {
436
                return epsg;
437
        }
438

    
439
        /*
440
         * (non-Javadoc)
441
         * @see org.gvsig.raster.cache.tile.provider.CacheStruct#getFileSize()
442
         */
443
        public String getFileSize() {
444
                return fileSize + "";
445
        }
446
        
447
        private boolean compareExtents(Point2D[] p, Point2D[] p1) {
448
                return (p[0].getX() == p1[0].getX() && p[0].getY() == p1[0].getY() &&
449
                                p[1].getX() == p1[1].getX() && p[1].getY() == p1[1].getY());
450
        }
451
        
452
        public double clipDecimals(double num, int n) {
453
                long m = (long) Math.pow(10, n);
454
                long aux = Math.round(num * m);
455
                return (double) aux / (double) m;
456
        }
457

    
458
}